From ca085fd7b7ba0cd12a6411cc0ff6a3380d82df0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20L=C3=B3pez-Ib=C3=A1=C3=B1ez?= Date: Sat, 9 Aug 2008 12:37:32 +0000 Subject: [PATCH] re PR c++/17880 (-Wsequence-point doesn't warn inside if, while, do conditions, for beg/cond/end expressions etc.) 2008-08-09 Manuel Lopez-Ibanez PR c/17880 * c-typeck.c (digest_init): Call verify_sequence_points from here. (c_finish_return): Likewise. (c_start_case): Likewise. * c-common.c (warn_for_collisions_1): Use explicit location in warning. * c-parser.c (c_parser_condition): New. Call verify_sequence_points. (c_parser_paren_condition): Call c_parser_condition. (c_parser_for_statement): Call c_parser_condition. testsuite/ * gcc.dg/sequence-pt-pr17880.c: New. From-SVN: r138904 --- gcc/ChangeLog | 13 ++++++ gcc/c-common.c | 6 ++- gcc/c-parser.c | 30 +++++++----- gcc/c-typeck.c | 9 ++++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/sequence-pt-pr17880.c | 54 ++++++++++++++++++++++ 6 files changed, 104 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/sequence-pt-pr17880.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9bc8214a9cd..12b9e4fafb9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2008-08-09 Manuel Lopez-Ibanez + + PR c/17880 + * c-typeck.c (digest_init): Call verify_sequence_points from here. + (c_finish_return): Likewise. + (c_start_case): Likewise. + * c-common.c (warn_for_collisions_1): Use explicit location in + warning. + * c-parser.c (c_parser_condition): New. Call + verify_sequence_points. + (c_parser_paren_condition): Call c_parser_condition. + (c_parser_for_statement): Call c_parser_condition. + 2008-08-09 Manuel Lopez-Ibanez PR 36901 diff --git a/gcc/c-common.c b/gcc/c-common.c index d2177bff2e1..bf75fe78e7b 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -1902,8 +1902,10 @@ warn_for_collisions_1 (tree written, tree writer, struct tlist *list, && DECL_NAME (list->expr)) { warned_ids = new_tlist (warned_ids, written, NULL_TREE); - warning (OPT_Wsequence_point, "operation on %qE may be undefined", - list->expr); + warning_at (EXPR_HAS_LOCATION (writer) + ? EXPR_LOCATION (writer) : input_location, + OPT_Wsequence_point, "operation on %qE may be undefined", + list->expr); } list = list->next; } diff --git a/gcc/c-parser.c b/gcc/c-parser.c index a2ea45f6a78..02fc7853fce 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -3791,6 +3791,23 @@ c_parser_statement_after_labels (c_parser *parser) parser->in_if_block = in_if_block; } +/* Parse the condition from an if, do, while or for statements. */ + +static tree +c_parser_condition (c_parser *parser) +{ + location_t loc; + tree cond; + loc = c_parser_peek_token (parser)->location; + cond = c_objc_common_truthvalue_conversion + (c_parser_expression_conv (parser).value); + if (CAN_HAVE_LOCATION_P (cond)) + SET_EXPR_LOCATION (cond, loc); + if (warn_sequence_point) + verify_sequence_points (cond); + return cond; +} + /* Parse a parenthesized condition from an if, do or while statement. condition: @@ -3799,15 +3816,10 @@ c_parser_statement_after_labels (c_parser *parser) static tree c_parser_paren_condition (c_parser *parser) { - location_t loc; tree cond; if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) return error_mark_node; - loc = c_parser_peek_token (parser)->location; - cond = c_objc_common_truthvalue_conversion - (c_parser_expression_conv (parser).value); - if (CAN_HAVE_LOCATION_P (cond)) - SET_EXPR_LOCATION (cond, loc); + cond = c_parser_condition (parser); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); return cond; } @@ -4073,7 +4085,6 @@ c_parser_for_statement (c_parser *parser) c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); } /* Parse the loop condition. */ - loc = c_parser_peek_token (parser)->location; if (c_parser_next_token_is (parser, CPP_SEMICOLON)) { c_parser_consume_token (parser); @@ -4081,10 +4092,7 @@ c_parser_for_statement (c_parser *parser) } else { - tree ocond = c_parser_expression_conv (parser).value; - cond = c_objc_common_truthvalue_conversion (ocond); - if (CAN_HAVE_LOCATION_P (cond)) - SET_EXPR_LOCATION (cond, loc); + cond = c_parser_condition (parser); c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); } /* Parse the increment expression. */ diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 61f385da25c..7646272dbd1 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -4801,6 +4801,9 @@ digest_init (tree type, tree init, bool strict_string, int require_constant) } } + if (warn_sequence_point) + verify_sequence_points (inside_init); + /* Any type can be initialized from an expression of the same type, optionally with braces. */ @@ -7166,6 +7169,9 @@ c_finish_return (tree retval) } retval = build2 (MODIFY_EXPR, TREE_TYPE (res), res, t); + + if (warn_sequence_point) + verify_sequence_points (retval); } ret_stmt = build_stmt (RETURN_EXPR, retval); @@ -7243,6 +7249,9 @@ c_start_case (tree exp) "converted to % in ISO C"); exp = default_conversion (exp); + + if (warn_sequence_point) + verify_sequence_points (exp); } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 31b271e94d0..4e3cf60c62b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-08-09 Manuel Lopez-Ibanez + + PR c/17880 + * gcc.dg/sequence-pt-pr17880.c: New. + 2008-08-09 Manuel Lopez-Ibanez PR c++/12242 diff --git a/gcc/testsuite/gcc.dg/sequence-pt-pr17880.c b/gcc/testsuite/gcc.dg/sequence-pt-pr17880.c new file mode 100644 index 00000000000..df706e577fb --- /dev/null +++ b/gcc/testsuite/gcc.dg/sequence-pt-pr17880.c @@ -0,0 +1,54 @@ +/* PR 17880 */ +/* { dg-do compile } */ +/* { dg-options "-Wsequence-point" } */ + +int +foo (int x) +{ + unsigned int a; + int b; + + b = (a += 5) > a; /* { dg-warning "undefined" "sequence point warning" } */ + b = (a += 5) + a == 10; /* { dg-warning "undefined" "sequence point warning" } */ + b = (a -= 5) > a; /* { dg-warning "undefined" "sequence point warning" } */ + b = (a -= 5) + a == 10; /* { dg-warning "undefined" "sequence point warning" } */ + b = a-- > a; /* { dg-warning "undefined" "sequence point warning" } */ + b = a-- + a == 10; /* { dg-warning "undefined" "sequence point warning" } */ + b = ++a > a; /* { dg-warning "undefined" "sequence point warning" } */ + b = ++a + a == 10; /* { dg-warning "undefined" "sequence point warning" } */ + + if ((a += 5) > a) return -1; /* { dg-warning "undefined" "sequence point warning" } */ + if ((a += 5) + a == 10) return -1; /* { dg-warning "undefined" "sequence point warning" } */ + if ((a -= 5) > a) return -1; /* { dg-warning "undefined" "sequence point warning" } */ + if ((a -= 5) + a == 10) return -1; /* { dg-warning "undefined" "sequence point warning" } */ + if (a-- > a) return -1; /* { dg-warning "undefined" "sequence point warning" } */ + if (a-- + a == 10) return -1; /* { dg-warning "undefined" "sequence point warning" } */ + if (++a > a) return -1; /* { dg-warning "undefined" "sequence point warning" } */ + if (++a + a == 10) return -1; /* { dg-warning "undefined" "sequence point warning" } */ + do {} while ((a += 5) > a); /* { dg-warning "undefined" "sequence point warning" } */ + while ((a += 5) > a); /* { dg-warning "undefined" "sequence point warning" } */ + for ((a += 5) > a;;); /* { dg-warning "undefined" "sequence point warning" } */ + for (b = (a += 5) > a;;); /* { dg-warning "undefined" "sequence point warning" } */ + for (; (a += 5) > a;); /* { dg-warning "undefined" "sequence point warning" } */ + for (;; b = (a += 5) > a); /* { dg-warning "undefined" "sequence point warning" } */ + for (;; a++ + a++); /* { dg-warning "undefined" "sequence point warning" } */ + if (a) a++ - a--; /* { dg-warning "undefined" "sequence point warning" } */ + ((a +=5) > a) ? a : b; /* { dg-warning "undefined" "sequence point warning" } */ + return (a++ - a--); /* { dg-warning "undefined" "sequence point warning" } */ +} + +void bar (int i) +{ + int a = i++ - i++; /* { dg-warning "undefined" "sequence point warning" } */ +} + +void baz (int i) +{ + switch (i++ + i++) /* { dg-warning "undefined" "sequence point warning" } */ + { + case 1: + i++ - i++; /* { dg-warning "undefined" "sequence point warning" } */ + case 2: + break; + } +}