aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2021-03-09 19:23:48 -0500
committerMarek Polacek <polacek@redhat.com>2021-03-23 10:54:27 -0400
commit831f9f768eb1fbf9a31d9a89591188b1487b6376 (patch)
treef669472b52c00bfee13bbfde872162e30f0a9e94 /gcc
parent212f4988f37ccf788c8c72b1dc952980bc9be3b7 (diff)
downloadgcc-831f9f768eb1fbf9a31d9a89591188b1487b6376.zip
gcc-831f9f768eb1fbf9a31d9a89591188b1487b6376.tar.gz
gcc-831f9f768eb1fbf9a31d9a89591188b1487b6376.tar.bz2
c++: Fix bogus warning in deprecated namespace [PR99318]
In GCC 10, I introduced cp_warn_deprecated_use_scopes so that we can handle attribute deprecated on a namespace declaration. This function walks the decl's contexts so that we warn for code like namespace [[deprecated]] N { struct S { }; } N::S s; We call cp_warn_deprecated_use_scopes when we encounter a TYPE_DECL. But in the following testcase we have a TYPE_DECL whose context is a deprecated function; that itself is not a reason to warn. This patch limits for which entities we call cp_warn_deprecated_use; essentially it's what can follow ::. I noticed that we didn't test that struct [[deprecated]] S { static void fn(); }; S::fn(); produces the expected warning, so I've added gen-attrs-73.C. gcc/cp/ChangeLog: PR c++/99318 * decl2.c (cp_warn_deprecated_use_scopes): Only call cp_warn_deprecated_use when decl is a namespace, class, or enum. gcc/testsuite/ChangeLog: PR c++/99318 * g++.dg/cpp0x/attributes-namespace6.C: New test. * g++.dg/cpp0x/gen-attrs-73.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/decl2.c3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/attributes-namespace6.C21
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/gen-attrs-73.C20
3 files changed, 43 insertions, 1 deletions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index c46100d..ef79f6c 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -5529,7 +5529,8 @@ cp_warn_deprecated_use_scopes (tree scope)
&& scope != error_mark_node
&& scope != global_namespace)
{
- if (cp_warn_deprecated_use (scope))
+ if ((TREE_CODE (scope) == NAMESPACE_DECL || OVERLOAD_TYPE_P (scope))
+ && cp_warn_deprecated_use (scope))
return;
if (TYPE_P (scope))
scope = CP_TYPE_CONTEXT (scope);
diff --git a/gcc/testsuite/g++.dg/cpp0x/attributes-namespace6.C b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace6.C
new file mode 100644
index 0000000..2fbc8e1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace6.C
@@ -0,0 +1,21 @@
+// PR c++/99318
+// { dg-do compile { target c++11 } }
+
+template <typename T>
+struct S {
+ [[deprecated("foo")]] unsigned m_fn (char const chr)
+ {
+ using index_t = unsigned;
+ return T::arr[static_cast<index_t>(chr)]; // { dg-bogus "deprecated" }
+ }
+};
+
+extern unsigned int arr[];
+
+struct R {
+ [[deprecated("foo")]] unsigned m_fn (char const chr)
+ {
+ using index_t = unsigned;
+ return arr[static_cast<index_t>(chr)]; // { dg-bogus "deprecated" }
+ }
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-73.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-73.C
new file mode 100644
index 0000000..75f4077
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-73.C
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++11 } }
+// Test attribute deprecated on :: with class, enum, and namespace.
+
+struct [[deprecated]] S { static void fn(); static const int s = 0; };
+union [[deprecated]] U { static void fn(); static const int u = 0; };
+enum [[deprecated]] E { X };
+enum class [[deprecated]] SE { Y };
+namespace [[deprecated]] N { struct S { }; }
+
+void
+g ()
+{
+ S::fn(); // { dg-warning "deprecated" }
+ (void) S::s; // { dg-warning "deprecated" }
+ U::fn(); // { dg-warning "deprecated" }
+ (void) U::u; // { dg-warning "deprecated" }
+ (void) E::X; // { dg-warning "deprecated" }
+ (void) SE::Y; // { dg-warning "deprecated" }
+ N::S s; // { dg-warning "deprecated" }
+}