Fix C++ side of PR c/70436 (missing -Wparentheses warnings)
authorPatrick Palka <ppalka@gcc.gnu.org>
Wed, 6 Apr 2016 23:10:14 +0000 (23:10 +0000)
committerPatrick Palka <ppalka@gcc.gnu.org>
Wed, 6 Apr 2016 23:10:14 +0000 (23:10 +0000)
gcc/cp/ChangeLog:

PR c/70436
* parser.c (cp_parser_iteration_statement): New parameter IF_P.
Pass it through to cp_parser_already_scoped_statement.
(cp_parser_already_scoped_statement): New parameter IF_P.  Pass
it through to cp_parser_statement.
(cp_parser_statement): Pass IF_P through to
cp_parser_iteration_statement.
(cp_parser_pragma): Adjust call to
cp_parser_iteration_statement.

gcc/testsuite/ChangeLog:

PR c/70436
* g++.dg/warn/Wparentheses-29.C: New test.

From-SVN: r234802

gcc/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Wparentheses-29.C [new file with mode: 0644]

index e51a523563776d6fa59c0468b786c6e0dd0d10b1..4ce1a5ab33c56cff172a1955c88091c94a972a1c 100644 (file)
@@ -1,3 +1,15 @@
+2016-04-06  Patrick Palka  <ppalka@gcc.gnu.org>
+
+       PR c/70436
+       * parser.c (cp_parser_iteration_statement): New parameter IF_P.
+       Pass it through to cp_parser_already_scoped_statement.
+       (cp_parser_already_scoped_statement): New parameter IF_P.  Pass
+       it through to cp_parser_statement.
+       (cp_parser_statement): Pass IF_P through to
+       cp_parser_iteration_statement.
+       (cp_parser_pragma): Adjust call to
+       cp_parser_iteration_statement.
+
 2016-04-06  Patrick Palka  <ppalka@gcc.gnu.org>
 
        PR c/70436
index 7e13c6e74f676e95ff7ff6acf314bbc1739a8d3e..28e01afc57232dc6d4fddbdaaf60c697c3301aee 100644 (file)
@@ -2104,7 +2104,7 @@ static tree cp_parser_selection_statement
 static tree cp_parser_condition
   (cp_parser *);
 static tree cp_parser_iteration_statement
-  (cp_parser *, bool);
+  (cp_parser *, bool *, bool);
 static bool cp_parser_for_init_statement
   (cp_parser *, tree *decl);
 static tree cp_parser_for
@@ -2127,7 +2127,7 @@ static void cp_parser_declaration_statement
 static tree cp_parser_implicitly_scoped_statement
   (cp_parser *, bool *, const token_indent_info &, vec<tree> * = NULL);
 static void cp_parser_already_scoped_statement
-  (cp_parser *, const token_indent_info &);
+  (cp_parser *, bool *, const token_indent_info &);
 
 /* Declarations [gram.dcl.dcl] */
 
@@ -10392,7 +10392,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
        case RID_WHILE:
        case RID_DO:
        case RID_FOR:
-         statement = cp_parser_iteration_statement (parser, false);
+         statement = cp_parser_iteration_statement (parser, if_p, false);
          break;
 
        case RID_CILK_FOR:
@@ -10947,7 +10947,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
            else
              {
                /* This if statement does not have an else clause.  If
-                  NESTED_IF is true, then the then-clause is an if
+                  NESTED_IF is true, then the then-clause has an if
                   statement which does have an else clause.  We warn
                   about the potential ambiguity.  */
                if (nested_if)
@@ -11544,7 +11544,7 @@ cp_parser_range_for_member_function (tree range, tree identifier)
    Returns the new WHILE_STMT, DO_STMT, FOR_STMT or RANGE_FOR_STMT.  */
 
 static tree
-cp_parser_iteration_statement (cp_parser* parser, bool ivdep)
+cp_parser_iteration_statement (cp_parser* parser, bool *if_p, bool ivdep)
 {
   cp_token *token;
   enum rid keyword;
@@ -11582,7 +11582,7 @@ cp_parser_iteration_statement (cp_parser* parser, bool ivdep)
        cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
        /* Parse the dependent statement.  */
        parser->in_statement = IN_ITERATION_STMT;
-       cp_parser_already_scoped_statement (parser, guard_tinfo);
+       cp_parser_already_scoped_statement (parser, if_p, guard_tinfo);
        parser->in_statement = in_statement;
        /* We're done with the while-statement.  */
        finish_while_stmt (statement);
@@ -11627,7 +11627,7 @@ cp_parser_iteration_statement (cp_parser* parser, bool ivdep)
 
        /* Parse the body of the for-statement.  */
        parser->in_statement = IN_ITERATION_STMT;
-       cp_parser_already_scoped_statement (parser, guard_tinfo);
+       cp_parser_already_scoped_statement (parser, if_p, guard_tinfo);
        parser->in_statement = in_statement;
 
        /* We're done with the for-statement.  */
@@ -11937,7 +11937,7 @@ cp_parser_implicitly_scoped_statement (cp_parser* parser, bool *if_p,
    scope.  */
 
 static void
-cp_parser_already_scoped_statement (cp_parser* parser,
+cp_parser_already_scoped_statement (cp_parser* parser, bool *if_p,
                                    const token_indent_info &guard_tinfo)
 {
   /* If the token is a `{', then we must take special action.  */
@@ -11946,7 +11946,7 @@ cp_parser_already_scoped_statement (cp_parser* parser,
       token_indent_info body_tinfo
        = get_token_indent_info (cp_lexer_peek_token (parser->lexer));
 
-      cp_parser_statement (parser, NULL_TREE, false, NULL);
+      cp_parser_statement (parser, NULL_TREE, false, if_p);
       token_indent_info next_tinfo
        = get_token_indent_info (cp_lexer_peek_token (parser->lexer));
       warn_for_misleading_indentation (guard_tinfo, body_tinfo, next_tinfo);
@@ -37310,7 +37310,7 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
            cp_parser_error (parser, "for, while or do statement expected");
            return false;
          }
-       cp_parser_iteration_statement (parser, true);
+       cp_parser_iteration_statement (parser, NULL, true);
        return true;
       }
 
index 2a785506710d54e1bbea058096f99d5232bd3772..d3c74edc9704301c0a7ceb0c1c5a34b025c2aecc 100644 (file)
@@ -1,3 +1,8 @@
+2016-04-06  Patrick Palka  <ppalka@gcc.gnu.org>
+
+       PR c/70436
+       * g++.dg/warn/Wparentheses-29.C: New test.
+
 2016-04-06  Patrick Palka  <ppalka@gcc.gnu.org>
 
        PR c/70436
diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-29.C b/gcc/testsuite/g++.dg/warn/Wparentheses-29.C
new file mode 100644 (file)
index 0000000..7832415
--- /dev/null
@@ -0,0 +1,135 @@
+/* PR c/70436  */
+/* { dg-options "-Wparentheses" }  */
+
+int a, b, c;
+void bar (void);
+void baz (void);
+
+void
+foo (void)
+{
+  int i, j;
+
+  if (a) /* { dg-warning "ambiguous" }  */
+    for (;;)
+      if (b)
+        bar ();
+      else
+        baz ();
+
+  if (a) /* { dg-warning "ambiguous" }  */
+    while (1)
+      if (b)
+        bar ();
+      else
+        baz ();
+
+  if (a) /* { dg-warning "ambiguous" }  */
+    while (1)
+      for (;;)
+        if (b)
+          bar ();
+        else
+          baz ();
+
+  if (a) /* { dg-warning "ambiguous" }  */
+    while (1)
+      while (1)
+        if (b)
+          bar ();
+  else
+    baz ();
+
+  if (a) /* { dg-warning "ambiguous" }  */
+    for (i = 0; i < 10; i++)
+      for (j = 0; j < 10; j++)
+        if (b)
+          bar ();
+  else
+    baz ();
+
+  if (a)
+    for (i = 0; i < 10; i++)
+      if (b) /* { dg-warning "ambiguous" }  */
+        for (j = 0; j < 10; j++)
+          if (c)
+            bar ();
+      else
+        baz ();
+
+  if (a) /* { dg-warning "ambiguous" }  */
+    for (i = 0; i < 10; i++)
+      if (b)
+        for (j = 0; j < 10; j++)
+          if (c)
+            bar ();
+          else
+            baz ();
+  else
+    bar ();
+
+  if (a) /* { dg-warning "ambiguous" }  */
+    for (;;)
+      if (b)
+        while (1)
+          if (a)
+            bar ();
+          else
+            baz ();
+      else
+        bar ();
+
+  if (a) /* { dg-warning "ambiguous" }  */
+    for (;;)
+      if (b)
+        while (1)
+          {
+            if (a) { bar (); } else { baz (); }
+          }
+      else
+        bar ();
+
+  if (a)
+    for (;;)
+      if (b)
+        bar ();
+      else
+        baz ();
+  else bar ();
+
+  if (a)
+    while (1)
+      if (b)
+        bar ();
+      else
+        baz ();
+  else bar ();
+
+  if (a)
+    for (;;)
+      {
+        if (b)
+          bar ();
+        else
+          baz ();
+      }
+
+  if (a)
+    {
+      for (;;)
+        if (b)
+          bar ();
+    }
+  else baz ();
+
+  if (a)
+    do
+      if (b) bar (); else baz ();
+    while (b);
+
+  if (a)
+    do
+      if (b) bar ();
+    while (b);
+  else baz ();
+}