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
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] */
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:
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)
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;
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);
/* 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. */
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. */
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);
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;
}
--- /dev/null
+/* 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 ();
+}