On 1/19/21 11:29 AM, Patrick Palka wrote:
Here, during partial instantiation of the generic lambda, tsubst_copy on
the CLASS_PLACEHOLDER_TEMPLATE of the CTAD placeholder U{0} yields a
(level-lowered) TEMPLATE_TEMPLATE_PARM rather than the corresponding
TEMPLATE_DECL. This later confuses do_class_deduction which expects
that the CLASS_PLACEHOLDER_TEMPLATE is always a TEMPLATE_DECL.
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?
OK.
gcc/cp/ChangeLog:
PR c++/95434
* pt.c (tsubst) <case TEMPLATE_TEMPLATE_PARM>: If tsubsting
CLASS_PLACEHOLDER_TEMPLATE yields a TEMPLATE_TEMPLATE_PARM,
adjust to its TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL.
gcc/testsuite/ChangeLog:
PR c++/95434
* g++.dg/cpp2a/lambda-generic9.C: New test.
---
gcc/cp/pt.c | 2 ++
gcc/testsuite/g++.dg/cpp2a/lambda-generic9.C | 9 +++++++++
2 files changed, 11 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/cpp2a/lambda-generic9.C
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d5d3d2fd040..2fed81520e3 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -15688,6 +15688,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain,
tree in_decl)
else if (tree pl = CLASS_PLACEHOLDER_TEMPLATE (t))
{
pl = tsubst_copy (pl, args, complain, in_decl);
+ if (TREE_CODE (pl) == TEMPLATE_TEMPLATE_PARM)
+ pl = TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (pl);
CLASS_PLACEHOLDER_TEMPLATE (r) = pl;
}
}
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-generic9.C
b/gcc/testsuite/g++.dg/cpp2a/lambda-generic9.C
new file mode 100644
index 00000000000..20ceb370c38
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/lambda-generic9.C
@@ -0,0 +1,9 @@
+// PR c++/95434
+// { dg-do compile { target c++20 } }
+
+template <class>
+void f() {
+ [] <template <class> class U> { U{0}; };
+}
+
+template void f<int>();