public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-1697] c++: extend lookup_template_class shortcut [PR110122]
@ 2023-06-11 15:27 Patrick Palka
  0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2023-06-11 15:27 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:682d401a6ba723b2bf98779d056efc8ff2640178

commit r14-1697-g682d401a6ba723b2bf98779d056efc8ff2640178
Author: Patrick Palka <ppalka@redhat.com>
Date:   Sun Jun 11 11:09:16 2023 -0400

    c++: extend lookup_template_class shortcut [PR110122]
    
    Here when substituting the injected class name A during regeneration of
    the lambda, we find ourselves in lookup_template_class for A<V> with
    V=_ZTAXtl3BarEE (i.e. the template parameter object for Foo{}).  The call
    to coerce_template_parms within then undesirably tries to make a copy of
    this class NTTP argument, which fails because Foo is not copyable.  But it
    seems clear that this testcase shouldn't require copyability of Foo.
    
    lookup_template_class has a shortcut for looking up the current class
    scope, which would avoid the problematic coerce_template_parms call, but
    the shortcut doesn't trigger because it only considers the innermost
    class scope which in this case in the lambda type.  So this patch fixes
    this by extending the lookup_template_class shortcut to consider outer
    class scopes too (and skipping over lambda types since they are never
    specialized from lookup_template_class).  We also need to avoid calling
    coerce_template_parms when specializing a templated non-template nested
    class for the first time (such as A::B in the testcase).  Coercion should
    be unnecessary there because the innermost arguments belong to the context
    and so should have already been coerced.
    
            PR c++/110122
    
    gcc/cp/ChangeLog:
    
            * pt.cc (lookup_template_class): Extend shortcut for looking up the
            current class scope to consider outer class scopes too, and use
            current_nonlambda_class_type instead of current_class_type.  Only
            call coerce_template_parms when specializing a primary template.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp2a/nontype-class57.C: New test.
            * g++.dg/cpp2a/nontype-class58.C: New test.

Diff:
---
 gcc/cp/pt.cc                                 | 19 +++++++++++++++----
 gcc/testsuite/g++.dg/cpp2a/nontype-class57.C | 25 +++++++++++++++++++++++++
 gcc/testsuite/g++.dg/cpp2a/nontype-class58.C | 20 ++++++++++++++++++++
 3 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 6a2cf2c123f..2345a18becc 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -9918,16 +9918,27 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context,
 	 template.  */
 
       /* Shortcut looking up the current class scope again.  */
-      if (current_class_type)
-	if (tree ti = CLASSTYPE_TEMPLATE_INFO (current_class_type))
+      for (tree cur = current_nonlambda_class_type ();
+	   cur != NULL_TREE;
+	   cur = get_containing_scope (cur))
+	{
+	  if (!CLASS_TYPE_P (cur))
+	    continue;
+
+	  tree ti = CLASSTYPE_TEMPLATE_INFO (cur);
+	  if (!ti || arg_depth > TMPL_ARGS_DEPTH (TI_ARGS (ti)))
+	    break;
+
 	  if (gen_tmpl == most_general_template (TI_TEMPLATE (ti))
 	      && comp_template_args (arglist, TI_ARGS (ti)))
-	    return current_class_type;
+	    return cur;
+	}
 
       /* Calculate the BOUND_ARGS.  These will be the args that are
 	 actually tsubst'd into the definition to create the
 	 instantiation.  */
-      arglist = coerce_template_parms (parmlist, arglist, gen_tmpl, complain);
+      if (PRIMARY_TEMPLATE_P (gen_tmpl))
+	arglist = coerce_template_parms (parmlist, arglist, gen_tmpl, complain);
 
       if (arglist == error_mark_node)
 	/* We were unable to bind the arguments.  */
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class57.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class57.C
new file mode 100644
index 00000000000..1520fc59f64
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class57.C
@@ -0,0 +1,25 @@
+// PR c++/110122
+// { dg-do compile { target c++20 } }
+
+struct Foo {
+  Foo() = default;
+  Foo(const Foo&) = delete;
+};
+
+template<Foo V>
+struct A {
+  A() {
+    [] { A a; }();
+    [this] { this; }();
+  }
+
+  struct B {
+    B() {
+      [] { A a; }();
+      [this] { this; }();
+    }
+  };
+};
+
+A<Foo{}> a;
+A<Foo{}>::B b;
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class58.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class58.C
new file mode 100644
index 00000000000..5bb335ca9e7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class58.C
@@ -0,0 +1,20 @@
+// PR c++/110122
+// { dg-do compile { target c++20 } }
+
+struct Foo {
+  Foo() = default;
+  constexpr Foo(const Foo&) { }
+};
+
+struct Bar {
+  Foo _;
+};
+
+template<Bar V>
+struct A {
+  A() {
+    [](auto){ A<V> d; }(0); // { dg-bogus "used before its definition" }
+  };
+};
+
+A<Bar{}> a;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-06-11 15:27 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-11 15:27 [gcc r14-1697] c++: extend lookup_template_class shortcut [PR110122] Patrick Palka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).