On Thu, 2017-06-08 at 18:49 +0200, Marek Polacek wrote: > This is the hopefully last incarnation of the patch. The change from > the > last time[0] is simpy that I've added a new test and the warning has > been > renamed to -Wmultistatement-macros. > > David - any another comments?
Thanks for working on this; looks useful. The new name is more accurate, but is rather long; oh well. As part of -Wall, users won't typically have to type it, so that's OK. [...] > diff --git gcc/c-family/c-warn.c gcc/c-family/c-warn.c > index 35321a6..d883330 100644 > --- gcc/c-family/c-warn.c > +++ gcc/c-family/c-warn.c [...] > + if (warning_at (body_loc, OPT_Wmultistatement_macros, > + "macro expands to multiple statements")) > + inform (guard_loc, "some parts of macro expansion are not > guarded by " > + "this conditional"); Is the guard necessarily a "conditional"? I take a "conditional" to mean an "if"; the guard could be a "for" or a "while" (or an "else", which still seems something of a stretch to me to call a "conditional"). Suggestion: word "this conditional" as "this %qs clause" and either (a) rework the code in c-indentation.c's guard_tinfo_to_string so that it's shared between these two warnings (i.e. to go from a RID_ to a const char *), or (b) just pass in a const char * identifying the guard clause token. > diff --git gcc/c-family/c.opt gcc/c-family/c.opt > index 37bb236..9dbe211 100644 > --- gcc/c-family/c.opt > +++ gcc/c-family/c.opt > @@ -698,6 +698,10 @@ Wmissing-field-initializers > C ObjC C++ ObjC++ Var(warn_missing_field_initializers) Warning > EnabledBy(Wextra) > Warn about missing fields in struct initializers. > > +Wmultistatement-macros > +C ObjC C++ ObjC++ Var(warn_multistatement_macros) Warning > LangEnabledBy(C ObjC C++ ObjC++,Wall) > +Warn about macros expanding to multiple statements in a body of a > conditional such as if, else, while, or for. Likewise; is "conditional" the right word here? Also, whether of not the statements are actually "in" the body of the guard is the issue here. How about: "Warn about unsafe multiple statement macros that appear to be guarded by a clause such as if, else, while, or for, in which only the first statement is actually guarded after the macro is expanded." or somesuch? > diff --git gcc/doc/invoke.texi gcc/doc/invoke.texi > index c116882..2fe16dd 100644 > --- gcc/doc/invoke.texi > +++ gcc/doc/invoke.texi > @@ -4496,6 +4497,29 @@ This warning is enabled by @option{-Wall}. > @opindex Wno-missing-include-dirs > Warn if a user-supplied include directory does not exist. > > +@item -Wmultistatement-macros > +@opindex Wmultistatement-macros > +@opindex Wno-multistatement-macros > +Warn about macros expanding to multiple statements in a body of a > conditional, > +such as @code{if}, @code{else}, @code{for}, or @code{while}. (as above). > +For example: > + > +@smallexample > +#define DOIT x++; y++ > +if (c) > + DOIT; > +@end smallexample > + > +will increment @code{y} unconditionally, not just when @code{c} > holds. > +The can usually be fixed by wrapping the macro in a do-while loop: > +@smallexample > +#define DOIT do @{ x++; y++; @} while (0) > +if (c) > + DOIT; > +@end smallexample > + > +This warning is enabled by @option{-Wall} in C and C++. > + > @item -Wparentheses > @opindex Wparentheses > @opindex Wno-parentheses Hope this is constructive Dave