https://gcc.gnu.org/g:708c393774188d74399ec75ef20a522444b09f92

commit r14-11591-g708c393774188d74399ec75ef20a522444b09f92
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon Apr 7 14:35:14 2025 -0400

    c++: self-dependent alias template [PR117530]
    
    Here, instantiating B<short> means instantiating A<short>, which means
    instantiating B<short>.  And then when we go to register the initial
    instantiation, it conflicts with the inner one.  Fixed by checking after
    tsubst whether there's already something in the hash table.  We already did
    something much like this in tsubst_decl, but that doesn't handle this case.
    
            PR c++/117530
    
    gcc/cp/ChangeLog:
    
            * pt.cc (instantiate_template): Check retrieve_specialization after
            tsubst.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp2a/lambda-uneval27.C: New test.
    
    (cherry picked from commit d034c78c7be613db3c25fddec1dd50222327117b)

Diff:
---
 gcc/cp/pt.cc                                 |  9 +++++++++
 gcc/testsuite/g++.dg/cpp2a/lambda-uneval27.C | 10 ++++++++++
 2 files changed, 19 insertions(+)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index d41df4f230ce..3a5ffd8b683e 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -22258,6 +22258,15 @@ instantiate_template (tree tmpl, tree orig_args, 
tsubst_flags_t complain)
       return error_mark_node;
     }
 
+  /* Substituting the type might have recursively instantiated this
+     same alias (c++/117530).  */
+  if (DECL_ALIAS_TEMPLATE_P (gen_tmpl)
+      && (spec = retrieve_specialization (gen_tmpl, targ_ptr, hash)))
+    {
+      pop_deferring_access_checks ();
+      return spec;
+    }
+
   /* The DECL_TI_TEMPLATE should always be the immediate parent
      template, not the most general template.  */
   DECL_TI_TEMPLATE (fndecl) = tmpl;
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-uneval27.C 
b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval27.C
new file mode 100644
index 000000000000..941fe636f6d5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval27.C
@@ -0,0 +1,10 @@
+// PR c++/117530
+// { dg-do compile { target c++20 } }
+
+template <class> struct A;
+template <class T> using B = decltype([]() -> A<T>::X { return 0; });
+template <class T> struct A {
+  typedef int X;
+  typedef B<T> U;
+};
+B<short> b;

Reply via email to