From: Patrick Palka Date: Tue, 12 Jan 2021 14:34:41 +0000 (-0500) Subject: c++: Fix ICE with CTAD in concept [PR98611] X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e0bec6ceac47752616dd9fe0801344ed45db2fd3;p=gcc.git c++: Fix ICE with CTAD in concept [PR98611] This patch teaches cp_walk_subtrees to visit the template represented by a CTAD placeholder, which would otherwise be not visited during find_template_parameters. The template may be a template template parameter (as in the first testcase), or it may implicitly use the template parameters of an enclosing class template (as in the second testcase), and in either case we need to visit this tree to record the template parameters used therein for later satisfaction. gcc/cp/ChangeLog: PR c++/98611 * tree.c (cp_walk_subtrees) : Visit the template of a CTAD placeholder. gcc/testsuite/ChangeLog: PR c++/98611 * g++.dg/cpp2a/concepts-ctad1.C: New test. * g++.dg/cpp2a/concepts-ctad2.C: New test. --- diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index c536eb581a7..d339036e88e 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -5173,12 +5173,15 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func, result = NULL_TREE; switch (code) { + case TEMPLATE_TYPE_PARM: + if (template_placeholder_p (*tp)) + WALK_SUBTREE (CLASS_PLACEHOLDER_TEMPLATE (*tp)); + /* Fall through. */ case DEFERRED_PARSE: case TEMPLATE_TEMPLATE_PARM: case BOUND_TEMPLATE_TEMPLATE_PARM: case UNBOUND_CLASS_TEMPLATE: case TEMPLATE_PARM_INDEX: - case TEMPLATE_TYPE_PARM: case TYPEOF_TYPE: case UNDERLYING_TYPE: /* None of these have subtrees other than those already walked diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C new file mode 100644 index 00000000000..ec2e4b014d7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad1.C @@ -0,0 +1,16 @@ +// PR c++/98611 +// { dg-do compile { target c++20 } } + +template +concept IsSame = __is_same(T, U); + +template class _Class> +concept IsInstantiationOf = requires(T object) { + { _Class{object} } -> IsSame; +}; + +template struct Degrees {}; +static_assert(IsInstantiationOf, Degrees>); + +template struct NotDegrees {}; +static_assert(!IsInstantiationOf, NotDegrees>); diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C new file mode 100644 index 00000000000..0d7f9790777 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ctad2.C @@ -0,0 +1,13 @@ +// PR c++/98611 +// { dg-do compile { target c++20 } } + +template +struct S { + template struct Tmpl { Tmpl(T); }; + + template + requires requires (T object) { Tmpl{object}; } + static int f(T); +}; + +int a = S::f(0);