From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1734) id 974993850427; Tue, 23 Mar 2021 14:56:28 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 974993850427 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Marek Polacek To: gcc-cvs@gcc.gnu.org Subject: [gcc r11-7789] c++: Fix bogus warning in deprecated namespace [PR99318] X-Act-Checkin: gcc X-Git-Author: Marek Polacek X-Git-Refname: refs/heads/master X-Git-Oldrev: 212f4988f37ccf788c8c72b1dc952980bc9be3b7 X-Git-Newrev: 831f9f768eb1fbf9a31d9a89591188b1487b6376 Message-Id: <20210323145628.974993850427@sourceware.org> Date: Tue, 23 Mar 2021 14:56:28 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Mar 2021 14:56:28 -0000 https://gcc.gnu.org/g:831f9f768eb1fbf9a31d9a89591188b1487b6376 commit r11-7789-g831f9f768eb1fbf9a31d9a89591188b1487b6376 Author: Marek Polacek Date: Tue Mar 9 19:23:48 2021 -0500 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. Diff: --- gcc/cp/decl2.c | 3 ++- gcc/testsuite/g++.dg/cpp0x/attributes-namespace6.C | 21 +++++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/gen-attrs-73.C | 20 ++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index c46100de89a..ef79f6cc6d1 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 00000000000..2fbc8e1158f --- /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 +struct S { + [[deprecated("foo")]] unsigned m_fn (char const chr) + { + using index_t = unsigned; + return T::arr[static_cast(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(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 00000000000..75f4077af7b --- /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" } +}