diff options
author | Martin Sebor <msebor@redhat.com> | 2020-02-24 10:14:16 -0700 |
---|---|---|
committer | Martin Sebor <msebor@redhat.com> | 2020-02-24 10:14:16 -0700 |
commit | b73547e40e0b2b6621feec59c9cc65312eddbc6d (patch) | |
tree | 7413d2624f1b28fb895787b1e9cc8ce08a3f462e /gcc/cp | |
parent | 004f2c07b6d3fa543f0fe86c55a7b3c227de2bb6 (diff) | |
download | gcc-b73547e40e0b2b6621feec59c9cc65312eddbc6d.zip gcc-b73547e40e0b2b6621feec59c9cc65312eddbc6d.tar.gz gcc-b73547e40e0b2b6621feec59c9cc65312eddbc6d.tar.bz2 |
PR c++/93804 - exempt extern C headers from -Wredundant-tags
gcc/cp/ChangeLog:
PR c++/93804
* parser.c (cp_parser_check_class_key): Avoid issuing -Wredundant-tags
in shared C/C++ code in headers.
gcc/testsuite/ChangeLog:
PR c++/93804
* g++.dg/warn/Wredundant-tags-4.C: New test.
* g++.dg/warn/Wredundant-tags-5.C: New test.
* g++.dg/warn/Wredundant-tags-5.h: New test.
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/parser.c | 64 |
2 files changed, 58 insertions, 12 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cc0929a..9c212d9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2020-02-24 Martin Sebor <msebor@redhat.com> + + PR c++/93804 + * parser.c (cp_parser_check_class_key): Avoid issuing -Wredundant-tags + in shared C/C++ code in headers. + 2020-02-24 Marek Polacek <polacek@redhat.com> PR c++/93869 - ICE with -Wmismatched-tags. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 01936e8..8e52fef 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -30837,15 +30837,31 @@ cp_parser_maybe_warn_enum_key (cp_parser *parser, location_t key_loc, /* The enum-key is redundant for uses of the TYPE that are not declarations and for which name lookup returns just the type itself. */ - if (decl == type_decl) - { - gcc_rich_location richloc (key_loc); - richloc.add_fixit_remove (key_loc); - warning_at (&richloc, OPT_Wredundant_tags, - "redundant enum-key %<enum%s%> in reference to %q#T", - (scoped_key == RID_CLASS ? " class" - : scoped_key == RID_STRUCT ? " struct" : ""), type); + if (decl != type_decl) + return; + + if (scoped_key != RID_CLASS + && scoped_key != RID_STRUCT + && current_lang_name != lang_name_cplusplus + && current_namespace == global_namespace) + { + /* Avoid issuing the diagnostic for apparently redundant (unscoped) + enum tag in shared C/C++ code in files (such as headers) included + in the main source file. */ + const line_map_ordinary *map = NULL; + linemap_resolve_location (line_table, key_loc, + LRK_MACRO_DEFINITION_LOCATION, + &map); + if (!MAIN_FILE_P (map)) + return; } + + gcc_rich_location richloc (key_loc); + richloc.add_fixit_remove (key_loc); + warning_at (&richloc, OPT_Wredundant_tags, + "redundant enum-key %<enum%s%> in reference to %q#T", + (scoped_key == RID_CLASS ? " class" + : scoped_key == RID_STRUCT ? " struct" : ""), type); } /* Describes the set of declarations of a struct, class, or class template @@ -31005,6 +31021,13 @@ cp_parser_check_class_key (cp_parser *parser, location_t key_loc, && class_key != union_type) return; + /* Only consider the true class-keys below and ignore typename_type, + etc. that are not C++ class-keys. */ + if (class_key != class_type + && class_key != record_type + && class_key != union_type) + return; + tree type_decl = TYPE_MAIN_DECL (type); tree name = DECL_NAME (type_decl); /* Look up the NAME to see if it unambiguously refers to the TYPE @@ -31017,15 +31040,32 @@ cp_parser_check_class_key (cp_parser *parser, location_t key_loc, neither definitions of it nor declarations, and for which name lookup returns just the type itself. */ bool key_redundant = !def_p && !decl_p && decl == type_decl; + + if (key_redundant + && class_key != class_type + && current_lang_name != lang_name_cplusplus + && current_namespace == global_namespace) + { + /* Avoid issuing the diagnostic for apparently redundant struct + and union class-keys in shared C/C++ code in files (such as + headers) included in the main source file. */ + const line_map_ordinary *map = NULL; + linemap_resolve_location (line_table, key_loc, + LRK_MACRO_DEFINITION_LOCATION, + &map); + if (!MAIN_FILE_P (map)) + key_redundant = false; + } + if (key_redundant) { gcc_rich_location richloc (key_loc); richloc.add_fixit_remove (key_loc); warning_at (&richloc, OPT_Wredundant_tags, - "redundant class-key %qs in reference to %q#T", - class_key == union_type ? "union" - : class_key == record_type ? "struct" : "class", - type); + "redundant class-key %qs in reference to %q#T", + class_key == union_type ? "union" + : class_key == record_type ? "struct" : "class", + type); } if (seen_as_union || !warn_mismatched_tags) |