On Thu, 10 Aug 2023, Jason Merrill wrote:

> On 8/10/23 12:09, Patrick Palka wrote:
> > Booststrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> > trunk and perhaps 13?
> > 
> > -- >8 --
> > 
> > We shouldn't issue a "declared static but never defined" warning
> > for a deduction guide (declared in an anonymous namespace).
> > 
> >     PR c++/106604
> > 
> > gcc/cp/ChangeLog:
> > 
> >     * decl.cc (wrapup_namespace_globals): Don't issue a
> >     -Wunused-function warning for a deduction guide.
> 
> Maybe instead of special casing this here we could set DECL_INITIAL on
> deduction guides so they look defined?

That seems to work, but it requires some tweaks in duplicate_decls to keep
saying "declared" instead of "defined" when diagnosing a deduction guide
redeclaration.  I'm not sure which approach is preferable?

-- >8 --

gcc/cp/ChangeLog:

        * decl.cc (duplicate_decls): When diagnosing a redeclared
        deduction guide, ensure we say "declared" instead of "defined".
        (redeclaration_error_message): Move up deduction guide tests.
        (grokfndecl): Set DECL_INITIAL to void_node for a deduction
        guide.

gcc/testsuite/ChangeLog:

        * g++.dg/cpp1z/class-deduction116.C: New test.
---
 gcc/cp/decl.cc                                | 23 +++++++++++--------
 .../g++.dg/cpp1z/class-deduction116.C         |  5 ++++
 2 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 2b3fb313166..70dcff7aa8c 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -2025,7 +2025,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, 
bool was_hidden)
          error_at (newdecl_loc, errmsg, newdecl);
          if (DECL_NAME (olddecl) != NULL_TREE)
            inform (olddecl_loc,
-                   (DECL_INITIAL (olddecl) && namespace_bindings_p ())
+                   (DECL_INITIAL (olddecl)
+                    && !deduction_guide_p (olddecl)
+                    && namespace_bindings_p ())
                    ? G_("%q#D previously defined here")
                    : G_("%q#D previously declared here"), olddecl);
          return error_mark_node;
@@ -3271,6 +3273,10 @@ redeclaration_error_message (tree newdecl, tree olddecl)
       /* We'll complain about linkage mismatches in
         warn_extern_redeclared_static.  */
 
+      if (deduction_guide_p (olddecl)
+         && deduction_guide_p (newdecl))
+       return G_("deduction guide %q+D redeclared");
+
       /* Defining the same name twice is no good.  */
       if (decl_defined_p (olddecl)
          && decl_defined_p (newdecl))
@@ -3298,10 +3304,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.  */
@@ -3330,6 +3332,10 @@ redeclaration_error_message (tree newdecl, tree olddecl)
       if (DECL_TEMPLATE_RESULT (newdecl) == DECL_TEMPLATE_RESULT (olddecl))
        return NULL;
 
+      if (deduction_guide_p (olddecl)
+         && deduction_guide_p (newdecl))
+       return G_("deduction guide %q+D redeclared");
+
       nt = DECL_TEMPLATE_RESULT (newdecl);
       if (DECL_TEMPLATE_INFO (nt))
        nt = DECL_TEMPLATE_RESULT (template_for_substitution (nt));
@@ -3356,10 +3362,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
@@ -10353,6 +10355,9 @@ grokfndecl (tree ctype,
       DECL_CXX_DESTRUCTOR_P (decl) = 1;
       DECL_NAME (decl) = dtor_identifier;
       break;
+    case sfk_deduction_guide:
+      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 00000000000..00f6d5fef41
--- /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" }
+}
-- 
2.42.0.rc1


> 
> > gcc/testsuite/ChangeLog:
> > 
> >     * g++.dg/cpp1z/class-deduction116.C: New test.
> > ---
> >   gcc/cp/decl.cc                                  | 1 +
> >   gcc/testsuite/g++.dg/cpp1z/class-deduction116.C | 8 ++++++++
> >   2 files changed, 9 insertions(+)
> >   create mode 100644 gcc/testsuite/g++.dg/cpp1z/class-deduction116.C
> > 
> > diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
> > index 792ab330dd0..9fe3a0b98fd 100644
> > --- a/gcc/cp/decl.cc
> > +++ b/gcc/cp/decl.cc
> > @@ -856,6 +856,7 @@ wrapup_namespace_globals ()
> >           && !TREE_PUBLIC (decl)
> >           && !DECL_ARTIFICIAL (decl)
> >           && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)
> > +         && !deduction_guide_p (decl)
> >           && !warning_suppressed_p (decl, OPT_Wunused_function))
> >         warning_at (DECL_SOURCE_LOCATION (decl),
> >                     OPT_Wunused_function,
> > 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 00000000000..00f6d5fef41
> > --- /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" }
> > +}
> 
> 

Reply via email to