re PR c++/17880 (-Wsequence-point doesn't warn inside if, while, do conditions, for...
authorManuel López-Ibáñez <manu@gcc.gnu.org>
Sat, 9 Aug 2008 12:37:32 +0000 (12:37 +0000)
committerManuel López-Ibáñez <manu@gcc.gnu.org>
Sat, 9 Aug 2008 12:37:32 +0000 (12:37 +0000)
2008-08-09  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>

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
gcc/c-common.c
gcc/c-parser.c
gcc/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/sequence-pt-pr17880.c [new file with mode: 0644]

index 9bc8214..12b9e4f 100644 (file)
@@ -1,5 +1,18 @@
 2008-08-09  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
 
+       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  <manu@gcc.gnu.org>
+
        PR 36901
        * diagnostic.def (DK_PEDWARN, DK_PERMERROR): New.  
        * diagnostic.c (pedantic_warning_kind, permissive_error_kind):
index d2177bf..bf75fe7 100644 (file)
@@ -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;
     }
index a2ea45f..02fc785 100644 (file)
@@ -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.  */
index 61f385d..7646272 100644 (file)
@@ -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 %<int%> in ISO C");
 
          exp = default_conversion (exp);
+
+         if (warn_sequence_point)
+           verify_sequence_points (exp);
        }
     }
 
index 31b271e..4e3cf60 100644 (file)
@@ -1,5 +1,10 @@
 2008-08-09  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
 
+       PR c/17880
+       * gcc.dg/sequence-pt-pr17880.c: New.
+
+2008-08-09  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
+
        PR c++/12242
        * g++.dg/warn/pr12242.C: New.
        
diff --git a/gcc/testsuite/gcc.dg/sequence-pt-pr17880.c b/gcc/testsuite/gcc.dg/sequence-pt-pr17880.c
new file mode 100644 (file)
index 0000000..df706e5
--- /dev/null
@@ -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;
+    }
+}