From 8a6eab343adef92f8d20a4a59bafdfa8e0b67e55 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 2 Aug 2017 11:56:54 +0000 Subject: [PATCH] re PR c/81448 (False positive -Werror=multistatement-macros in openssl) PR c/81448 PR c/81306 * c-warn.c (warn_for_multistatement_macros): Prevent bogus warnings. Avoid walking MACRO_MAP_LOCATIONS. * c-c++-common/Wmultistatement-macros-13.c: New test. From-SVN: r250822 --- gcc/c-family/c-warn.c | 52 +++++---- gcc/c/ChangeLog | 5 + gcc/testsuite/ChangeLog | 4 + .../c-c++-common/Wmultistatement-macros-13.c | 104 ++++++++++++++++++ 4 files changed, 144 insertions(+), 21 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/Wmultistatement-macros-13.c diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c index 505070e5586..e970ab2a00d 100644 --- a/gcc/c-family/c-warn.c +++ b/gcc/c-family/c-warn.c @@ -2457,34 +2457,44 @@ warn_for_multistatement_macros (location_t body_loc, location_t next_loc, || body_loc_exp == next_loc_exp) return; - /* Find the macro map for the macro expansion BODY_LOC. */ - const line_map *map = linemap_lookup (line_table, body_loc); - const line_map_macro *macro_map = linemap_check_macro (map); - - /* Now see if the following token is coming from the same macro - expansion. If it is, it's a problem, because it should've been - parsed at this point. We only look at odd-numbered indexes - within the MACRO_MAP_LOCATIONS array, i.e. the spelling locations - of the tokens. */ - bool found_guard = false; - bool found_next = false; - for (unsigned int i = 1; - i < 2 * MACRO_MAP_NUM_MACRO_TOKENS (macro_map); - i += 2) - { - if (MACRO_MAP_LOCATIONS (macro_map)[i] == next_loc_exp) - found_next = true; - if (MACRO_MAP_LOCATIONS (macro_map)[i] == guard_loc_exp) - found_guard = true; - } + /* Find the macro maps for the macro expansions. */ + const line_map *body_map = linemap_lookup (line_table, body_loc); + const line_map *next_map = linemap_lookup (line_table, next_loc); + const line_map *guard_map = linemap_lookup (line_table, guard_loc); + + /* Now see if the following token (after the body) is coming from the + same macro expansion. If it is, it might be a problem. */ + if (body_map != next_map) + return; /* The conditional itself must not come from the same expansion, because we don't want to warn about #define IF if (x) x++; y++ and similar. */ - if (!found_next || found_guard) + if (guard_map == body_map) return; + /* Handle the case where NEXT and BODY come from the same expansion while + GUARD doesn't, yet we shouldn't warn. E.g. + + #define GUARD if (...) + #define GUARD2 GUARD + + and in the definition of another macro: + + GUARD2 + foo (); + return 1; + */ + while (linemap_macro_expansion_map_p (guard_map)) + { + const line_map_macro *mm = linemap_check_macro (guard_map); + guard_loc_exp = MACRO_MAP_EXPANSION_POINT_LOCATION (mm); + guard_map = linemap_lookup (line_table, guard_loc_exp); + if (guard_map == body_map) + return; + } + 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 " diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index c89af1d5776..6c7b585fb83 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -3,6 +3,11 @@ PR c/81289 * c-parser.c (c_parser_unary_expression): Use set_error. + PR c/81448 + PR c/81306 + * c-warn.c (warn_for_multistatement_macros): Prevent bogus + warnings. Avoid walking MACRO_MAP_LOCATIONS. + 2017-07-31 Jan Hubicka Martin Liska diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a6d97e861f1..9730b0cafa6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -3,6 +3,10 @@ PR c/81289 * gcc.dg/noncompile/pr81289.c: New test. + PR c/81448 + PR c/81306 + * c-c++-common/Wmultistatement-macros-13.c: New test. + 2017-08-02 Jakub Jelinek PR c++/81640 diff --git a/gcc/testsuite/c-c++-common/Wmultistatement-macros-13.c b/gcc/testsuite/c-c++-common/Wmultistatement-macros-13.c new file mode 100644 index 00000000000..9f42e268d9f --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wmultistatement-macros-13.c @@ -0,0 +1,104 @@ +/* PR c/81448 */ +/* { dg-do compile } */ +/* { dg-options "-Wmultistatement-macros" } */ + +extern int i; + +#define BAD4 i++; i++ /* { dg-warning "macro expands to multiple statements" } */ +#define BAD5 i++; i++ /* { dg-warning "macro expands to multiple statements" } */ +#define BAD6 i++; i++ /* { dg-warning "macro expands to multiple statements" } */ +#define BAD7 i++; i++ /* { dg-warning "macro expands to multiple statements" } */ +#define BAD8 i++; i++ /* { dg-warning "macro expands to multiple statements" } */ +#define BAD9 i++; i++ /* { dg-warning "macro expands to multiple statements" } */ +#define IF if (1) /* { dg-message "not guarded by this 'if' clause" } */ +#define IF2 IF /* { dg-message "in expansion of macro .IF." } */ +#define BADB7 BAD7 /* { dg-message "in expansion of macro .BAD7." } */ +#define BADB8 BAD8 /* { dg-message "in expansion of macro .BAD8." } */ +#define BADB9 BAD9 /* { dg-message "in expansion of macro .BAD9." } */ + +#define FN0 \ +void fn0 (void) \ +{ \ + IF \ + i++; \ + return; \ +} + +#define FN1 \ +void fn1 (void) \ +{ \ + IF2 \ + i++; \ + return; \ +} + +#define FN2 \ +void fn2 (void) \ +{ \ + if (1) \ + i++; \ + return; \ +} + +#define TOP FN3 +#define FN3 \ +void fn3 (void) \ +{ \ + IF \ + i++; \ + return; \ +} + +#define TOP2 FN4 /* { dg-message "in expansion of macro .FN4." } */ +#define FN4 \ +void fn4 (void) \ +{ \ + IF2 /* { dg-message "in expansion of macro .IF2." } */ \ + BAD4; /* { dg-message "in expansion of macro .BAD4." } */ \ +} + +#define FN5 \ +void fn5 (void) \ +{ \ + IF /* { dg-message "in expansion of macro .IF." } */ \ + BAD5; /* { dg-message "in expansion of macro .BAD5." } */ \ +} + +#define FN6 \ +void fn6 (void) \ +{ \ + if (1) /* { dg-message "not guarded by this 'if' clause" } */ \ + BAD6; /* { dg-message "in expansion of macro .BAD6." } */ \ +} + +#define FN7 \ +void fn7 (void) \ +{ \ + if (1) /* { dg-message "not guarded by this 'if' clause" } */ \ + BADB7; /* { dg-message "in expansion of macro .BADB7." } */ \ +} + +#define FN8 \ +void fn8 (void) \ +{ \ + IF2 /* { dg-message "in expansion of macro .IF2." } */ \ + BADB8; /* { dg-message "in expansion of macro .BADB8." } */ \ +} + +#define FN9 \ +void fn9 (void) \ +{ \ + IF /* { dg-message "in expansion of macro .IF." } */ \ + BADB9; /* { dg-message "in expansion of macro .BADB9." } */ \ +} + +FN0 +FN1 +FN2 +TOP +TOP2 /* { dg-message "in expansion of macro .TOP2." } */ +FN5 /* { dg-message "in expansion of macro .FN5." } */ +FN6 /* { dg-message "in expansion of macro .FN6." } */ +FN7 /* { dg-message "in expansion of macro .FN7." } */ +FN8 /* { dg-message "in expansion of macro .FN8." } */ +FN9 /* { dg-message "in expansion of macro .FN9." } */ -- 2.30.2