This patch fixes a bogus -Wmultistatement-macros warning.  The code didn't
notice that what came after a guard such as else was actually wrapped in { }
which is a correct use.  This bogus warning only triggered when the body of
a conditional was coming from a different expansion than the conditional
itself.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2017-07-11  Marek Polacek  <pola...@redhat.com>

        PR c/81364
        * c-parser.c (c_parser_else_body): Don't warn about multistatement
        macro expansion if the body is in { }.
        (c_parser_while_statement): Likewise.
        (c_parser_for_statement): Likewise.

        * Wmultistatement-macros-12.c: New test.

diff --git gcc/c/c-parser.c gcc/c/c-parser.c
index f8fbc92..7524a73 100644
--- gcc/c/c-parser.c
+++ gcc/c/c-parser.c
@@ -5557,7 +5557,8 @@ c_parser_else_body (c_parser *parser, const 
token_indent_info &else_tinfo,
     }
   else
     {
-      body_loc_after_labels = c_parser_peek_token (parser)->location;
+      if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
+       body_loc_after_labels = c_parser_peek_token (parser)->location;
       c_parser_statement_after_labels (parser, NULL, chain);
     }
 
@@ -5811,6 +5812,7 @@ c_parser_while_statement (c_parser *parser, bool ivdep, 
bool *if_p)
     = get_token_indent_info (c_parser_peek_token (parser));
 
   location_t loc_after_labels;
+  bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
   body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
   c_finish_loop (loc, cond, NULL, body, c_break_label, c_cont_label, true);
   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
@@ -5820,7 +5822,7 @@ c_parser_while_statement (c_parser *parser, bool ivdep, 
bool *if_p)
     = get_token_indent_info (c_parser_peek_token (parser));
   warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
 
-  if (next_tinfo.type != CPP_SEMICOLON)
+  if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
     warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
                                    while_tinfo.location, RID_WHILE);
 
@@ -6109,6 +6111,7 @@ c_parser_for_statement (c_parser *parser, bool ivdep, 
bool *if_p)
     = get_token_indent_info (c_parser_peek_token (parser));
 
   location_t loc_after_labels;
+  bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
   body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
 
   if (is_foreach_statement)
@@ -6122,7 +6125,7 @@ c_parser_for_statement (c_parser *parser, bool ivdep, 
bool *if_p)
     = get_token_indent_info (c_parser_peek_token (parser));
   warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
 
-  if (next_tinfo.type != CPP_SEMICOLON)
+  if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
     warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
                                    for_tinfo.location, RID_FOR);
 
diff --git gcc/testsuite/c-c++-common/Wmultistatement-macros-12.c 
gcc/testsuite/c-c++-common/Wmultistatement-macros-12.c
index e69de29..ac8915c 100644
--- gcc/testsuite/c-c++-common/Wmultistatement-macros-12.c
+++ gcc/testsuite/c-c++-common/Wmultistatement-macros-12.c
@@ -0,0 +1,43 @@
+/* PR c/81364 */
+/* { dg-do compile } */
+/* { dg-options "-Wmultistatement-macros" } */
+
+#define FOO0 if (1) { } else
+#define TST0 \
+void bar0 (void) \
+{ \
+  FOO0 { } /* { dg-bogus "macro expands to multiple statements" } */ \
+}
+TST0
+
+#define FOO1 for (;;)
+#define TST1 \
+void bar1 (void) \
+{ \
+  FOO1 { } /* { dg-bogus "macro expands to multiple statements" } */ \
+}
+TST1
+
+#define FOO2 while (1)
+#define TST2 \
+void bar2 (void) \
+{ \
+  FOO2 { } /* { dg-bogus "macro expands to multiple statements" } */ \
+}
+TST2
+
+#define FOO3 switch (1)
+#define TST3 \
+void bar3 (void) \
+{ \
+  FOO3 { } /* { dg-bogus "macro expands to multiple statements" } */ \
+}
+TST3
+
+#define FOO4 if (1)
+#define TST4 \
+void bar4 (void) \
+{ \
+  FOO4 { } /* { dg-bogus "macro expands to multiple statements" } */ \
+}
+TST4

        Marek

Reply via email to