aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2020-02-24 10:14:16 -0700
committerMartin Sebor <msebor@redhat.com>2020-02-24 10:14:16 -0700
commitb73547e40e0b2b6621feec59c9cc65312eddbc6d (patch)
tree7413d2624f1b28fb895787b1e9cc8ce08a3f462e /gcc/cp
parent004f2c07b6d3fa543f0fe86c55a7b3c227de2bb6 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/parser.c64
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)