This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] PR c++/90590 Suppress warning for enumeration value not handled in switch warning
- From: Matthew Beliveau <mbelivea at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org, Marek Polacek <polacek at redhat dot com>, Jason Merrill <jason at redhat dot com>
- Date: Tue, 9 Jul 2019 11:18:53 -0400
- Subject: [C++ PATCH] PR c++/90590 Suppress warning for enumeration value not handled in switch warning
This patch suppresses the warning: "enumeration value not handled in
switch", for enumerators that are defined in system headers and use
reserved names.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2019-07-08 Matthew Beliveau <mbelivea@redhat.com>
PR c++/90590
* c-warn.c (c_do_switch_warnings): Suppress warning for enumerators
with reserved names that are in a system header.
* c-c++-common/pr90590-1.c: New test.
* c-c++-common/pr90590-1.h: New test.
* c-c++-common/pr90590-2.c: New test.
* c-c++-common/pr90590-2.h: New test.
diff --git gcc/c-family/c-warn.c gcc/c-family/c-warn.c
index b5d09e761d7..56ad23dd29c 100644
--- gcc/c-family/c-warn.c
+++ gcc/c-family/c-warn.c
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see
#include "gcc-rich-location.h"
#include "gimplify.h"
#include "c-family/c-indentation.h"
+#include "c-family/c-spellcheck.h"
#include "calls.h"
#include "stor-layout.h"
@@ -1592,8 +1593,12 @@ c_do_switch_warnings (splay_tree cases, location_t switch_location,
for (chain = TYPE_VALUES (type); chain; chain = TREE_CHAIN (chain))
{
tree value = TREE_VALUE (chain);
+ tree decl = NULL_TREE;
if (TREE_CODE (value) == CONST_DECL)
- value = DECL_INITIAL (value);
+ {
+ decl = value;
+ value = DECL_INITIAL (value);
+ }
node = splay_tree_lookup (cases, (splay_tree_key) value);
if (node)
{
@@ -1628,6 +1633,19 @@ c_do_switch_warnings (splay_tree cases, location_t switch_location,
if (cond && tree_int_cst_compare (cond, value))
continue;
+ /* If the enumerator is defined in a system header and uses a reserved
+ name, then we continue to avoid throwing a warning. */
+ if (decl == NULL_TREE)
+ decl = lookup_name (TREE_PURPOSE (chain));
+ if (decl && TREE_CODE (decl) == CONST_DECL)
+ {
+ const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
+ location_t loc = DECL_SOURCE_LOCATION (decl);
+ if (in_system_header_at (loc)
+ && name_reserved_for_implementation_p (name))
+ continue;
+ }
+
/* If there is a default_node, the only relevant option is
Wswitch-enum. Otherwise, if both are enabled then we prefer
to warn using -Wswitch because -Wswitch is enabled by -Wall
diff --git gcc/testsuite/c-c++-common/pr90590-1.c gcc/testsuite/c-c++-common/pr90590-1.c
new file mode 100644
index 00000000000..4997a3082d5
--- /dev/null
+++ gcc/testsuite/c-c++-common/pr90590-1.c
@@ -0,0 +1,15 @@
+// PR c++/90590
+// { dg-options -Wswitch }
+#include "pr90590-1.h"
+
+void
+g ()
+{
+ enum E e = _A;
+ switch (e) // { dg-bogus "enumeration value '_C' not handled in switch" }
+ {
+ case _A:
+ case _B:
+ break;
+ }
+}
diff --git gcc/testsuite/c-c++-common/pr90590-1.h gcc/testsuite/c-c++-common/pr90590-1.h
new file mode 100644
index 00000000000..22f1a7d5d52
--- /dev/null
+++ gcc/testsuite/c-c++-common/pr90590-1.h
@@ -0,0 +1,2 @@
+#pragma GCC system_header
+enum E { _A, _B, _C };
diff --git gcc/testsuite/c-c++-common/pr90590-2.c gcc/testsuite/c-c++-common/pr90590-2.c
new file mode 100644
index 00000000000..8aa65cf0afd
--- /dev/null
+++ gcc/testsuite/c-c++-common/pr90590-2.c
@@ -0,0 +1,8 @@
+#include "pr90590-2.h"
+
+void
+fn ()
+{
+ switch (c.b) // { dg-bogus "enumeration value" }
+ ;
+}
diff --git gcc/testsuite/c-c++-common/pr90590-2.h gcc/testsuite/c-c++-common/pr90590-2.h
new file mode 100644
index 00000000000..e4f8635576f
--- /dev/null
+++ gcc/testsuite/c-c++-common/pr90590-2.h
@@ -0,0 +1,4 @@
+#pragma GCC system_header
+struct {
+ enum { _A } b;
+} c;