Avoid printing informational notes when -Wmismatched-tags is suppressed in system...
authorMartin Sebor <msebor@redhat.com>
Tue, 7 Jul 2020 17:23:50 +0000 (11:23 -0600)
committerMartin Sebor <msebor@redhat.com>
Tue, 7 Jul 2020 17:23:50 +0000 (11:23 -0600)
Related:
PR c++/96063 - mismatched-tags warnings in stdlib headers

gcc/cp/ChangeLog:

PR c++/96063
* parser.c (class_decl_loc_t::diag_mismatched_tags): Print notes only
if warning_at returns nonzero.

gcc/testsuite/ChangeLog:

PR c++/96063
* g++.dg/warn/Wmismatched-tags-7.C: New test.
* g++.dg/warn/Wmismatched-tags-8.C: New test.

gcc/cp/parser.c
gcc/testsuite/g++.dg/warn/Wmismatched-tags-7.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Wmismatched-tags-8.C [new file with mode: 0644]

index 6e7637c6016fdb421666fa9a6ef26a6fb521fc37..e58d8eb298c0eedb74d6e0023a0f58cb6f1e769d 100644 (file)
@@ -31443,25 +31443,26 @@ class_decl_loc_t::diag_mismatched_tags (tree type_decl)
   /* Issue a warning for the first mismatched declaration.
      Avoid using "%#qT" since the class-key for the same type will
      be the same regardless of which one was used in the declaraion.  */
-  warning_at (loc, OPT_Wmismatched_tags,
-             "%qT declared with a mismatched class-key %qs",
-             type_decl, xmatchkstr);
-
-  /* Suggest how to avoid the warning for each instance since
-     the guidance may be different depending on context.  */
-  inform (loc,
-         (key_redundant_p
-          ? G_("remove the class-key or replace it with %qs")
-          : G_("replace the class-key with %qs")),
-         xpectkstr);
-
-  /* Also point to the first declaration or definition that guided
-     the decision to issue the warning above.  */
-  inform (cdlguide->location (idxguide),
-         (def_p
-          ? G_("%qT defined as %qs here")
-          : G_("%qT first declared as %qs here")),
-         type_decl, xpectkstr);
+  if (warning_at (loc, OPT_Wmismatched_tags,
+                 "%qT declared with a mismatched class-key %qs",
+                 type_decl, xmatchkstr))
+    {
+      /* Suggest how to avoid the warning for each instance since
+        the guidance may be different depending on context.  */
+      inform (loc,
+             (key_redundant_p
+              ? G_("remove the class-key or replace it with %qs")
+              : G_("replace the class-key with %qs")),
+             xpectkstr);
+
+      /* Also point to the first declaration or definition that guided
+        the decision to issue the warning above.  */
+      inform (cdlguide->location (idxguide),
+             (def_p
+              ? G_("%qT defined as %qs here")
+              : G_("%qT first declared as %qs here")),
+             type_decl, xpectkstr);
+    }
 
   /* Issue warnings for the remaining inconsistent declarations.  */
   for (unsigned i = idx + 1; i != ndecls; ++i)
@@ -31476,16 +31477,16 @@ class_decl_loc_t::diag_mismatched_tags (tree type_decl)
       key_redundant_p = key_redundant (i);
       /* Set the function declaration to print in diagnostic context.  */
       current_function_decl = function (i);
-      warning_at (loc, OPT_Wmismatched_tags,
-                 "%qT declared with a mismatched class-key %qs",
-                 type_decl, xmatchkstr);
-      /* Suggest how to avoid the warning for each instance since
-        the guidance may be different depending on context.  */
-      inform (loc,
-             (key_redundant_p
-              ? G_("remove the class-key or replace it with %qs")
-              : G_("replace the class-key with %qs")),
-             xpectkstr);
+      if (warning_at (loc, OPT_Wmismatched_tags,
+                     "%qT declared with a mismatched class-key %qs",
+                     type_decl, xmatchkstr))
+       /* Suggest how to avoid the warning for each instance since
+          the guidance may be different depending on context.  */
+       inform (loc,
+               (key_redundant_p
+                ? G_("remove the class-key or replace it with %qs")
+                : G_("replace the class-key with %qs")),
+               xpectkstr);
     }
 
   /* Restore the current function in case it was replaced above.  */
diff --git a/gcc/testsuite/g++.dg/warn/Wmismatched-tags-7.C b/gcc/testsuite/g++.dg/warn/Wmismatched-tags-7.C
new file mode 100644 (file)
index 0000000..3180c22
--- /dev/null
@@ -0,0 +1,13 @@
+/* Verify that -Wmismatched-tags doesn't print stray notes for warnings
+   disabled in system headers.
+  { dg-do "compile" }
+  { dg-options "-Wmismatched-tags" } */
+
+# 6 "Wmismatched-tags-7.C" 1
+# 1 "system-header.h" 1 3 4
+# 9 "system-header.h" 3 4
+class A;            // { dg-bogus "first declared" }
+struct A;           // { dg-bogus "replace" }
+# 12 "Wmismatched-tags-7.C" 2
+class B;            // { dg-message "first declared" }
+struct B;           // { dg-warning "\\\[-Wmismatched-tags" }
diff --git a/gcc/testsuite/g++.dg/warn/Wmismatched-tags-8.C b/gcc/testsuite/g++.dg/warn/Wmismatched-tags-8.C
new file mode 100644 (file)
index 0000000..0ebca3d
--- /dev/null
@@ -0,0 +1,22 @@
+/* Verify that #pragma GCC diagnostic works for -Wmismatched-tags.
+   { dg-do "compile" }
+   { dg-options "-Wmismatched-tags" } */
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic error "-Wmismatched-tags"
+class A;            // { dg-message "first declared"
+struct A;           // { dg-error "\\\[-Werror=mismatched-tags" }
+
+#pragma GCC diagnostic ignored "-Wmismatched-tags"
+class B;            // { dg-bogus "first declared" }
+struct B;
+
+#pragma GCC diagnostic warning "-Wmismatched-tags"
+class C;            // { dg-message "first declared"
+struct C;           // { dg-warning "\\\[-Wmismatched-tags" }
+#pragma GCC diagnostic pop
+
+class D;            // { dg-message "first declared"
+struct D;           // { dg-warning "\\\[-Wmismatched-tags" }
+
+// { dg-prune-output "some warnings being treated as errors" }