From f50f603cbfd05653555e9856360c83108bbd1d8a Mon Sep 17 00:00:00 2001 From: Patrick Palka <ppalka@redhat.com> Date: Fri, 11 Aug 2023 21:13:23 -0400 Subject: [PATCH] c++: bogus warning w/ deduction guide in anon ns [PR106604] Here we're unintentionally issuing a "declared static but never defined" warning from wrapup_namespace_globals for a deduction guide declared in an anonymous namespace. This patch fixes this by giving deduction guides a dummy DECL_INITIAL, which suppresses the warning and also allows us to simplify redeclaration checking for them. Co-authored-by: Jason Merrill <jason@redhat.com> PR c++/106604 gcc/cp/ChangeLog: * decl.cc (redeclaration_error_message): Remove special handling for deduction guides. (grokfndecl): Give deduction guides a dummy DECL_INITIAL. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/class-deduction74.C: Expect "defined" instead of "declared" in the repeated deduction guide diagnostics. * g++.dg/cpp1z/class-deduction116.C: New test. --- gcc/cp/decl.cc | 14 ++++++-------- gcc/testsuite/g++.dg/cpp1z/class-deduction116.C | 8 ++++++++ gcc/testsuite/g++.dg/cpp1z/class-deduction74.C | 14 +++++++------- 3 files changed, 21 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/class-deduction116.C diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index e21e015d5d8f..126c58180909 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -3297,10 +3297,6 @@ redeclaration_error_message (tree newdecl, tree olddecl) } } - if (deduction_guide_p (olddecl) - && deduction_guide_p (newdecl)) - return G_("deduction guide %q+D redeclared"); - /* [class.compare.default]: A definition of a comparison operator as defaulted that appears in a class shall be the first declaration of that function. */ @@ -3355,10 +3351,6 @@ redeclaration_error_message (tree newdecl, tree olddecl) } } - if (deduction_guide_p (olddecl) - && deduction_guide_p (newdecl)) - return G_("deduction guide %q+D redeclared"); - /* Core issue #226 (C++11): If a friend function template declaration specifies a @@ -10352,6 +10344,12 @@ grokfndecl (tree ctype, DECL_CXX_DESTRUCTOR_P (decl) = 1; DECL_NAME (decl) = dtor_identifier; break; + case sfk_deduction_guide: + /* Give deduction guides a definition even though they don't really + have one: the restriction that you can't repeat a deduction guide + makes them more like a definition anyway. */ + DECL_INITIAL (decl) = void_node; + break; default: break; } diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction116.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction116.C new file mode 100644 index 000000000000..00f6d5fef419 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction116.C @@ -0,0 +1,8 @@ +// PR c++/106604 +// { dg-do compile { target c++17 } } +// { dg-additional-options "-Wunused-function" } + +namespace { + template<class T> struct A { A(...); }; + A(bool) -> A<bool>; // { dg-bogus "never defined" } +} diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction74.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction74.C index fe113819a956..7bab882da7d9 100644 --- a/gcc/testsuite/g++.dg/cpp1z/class-deduction74.C +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction74.C @@ -7,20 +7,20 @@ template<typename> struct S { }; template<typename> struct X { }; -S() -> S<int>; // { dg-message "previously declared here|old declaration" } -S() -> S<int>; // { dg-error "redeclared" } +S() -> S<int>; // { dg-message "previously defined here|old declaration" } +S() -> S<int>; // { dg-error "redefinition" } X() -> X<int>; S() -> S<float>; // { dg-error "ambiguating new declaration of" } -S(bool) -> S<int>; // { dg-message "previously declared here" } -explicit S(bool) -> S<int>; // { dg-error "redeclared" } +S(bool) -> S<int>; // { dg-message "previously defined here" } +explicit S(bool) -> S<int>; // { dg-error "redefinition" } -explicit S(char) -> S<int>; // { dg-message "previously declared here" } -S(char) -> S<int>; // { dg-error "redeclared" } +explicit S(char) -> S<int>; // { dg-message "previously defined here" } +S(char) -> S<int>; // { dg-error "redefinition" } template<typename T> S(T, T) -> S<int>; // { dg-message "previously declared here" } template<typename T> X(T, T) -> X<int>; -template<typename T> S(T, T) -> S<int>; // { dg-error "redeclared" } +template<typename T> S(T, T) -> S<int>; // { dg-error "redefinition" } // OK: Use SFINAE. template<typename T> S(T) -> S<typename T::foo>; -- GitLab