From: Patrick Palka Date: Mon, 9 Nov 2020 23:12:42 +0000 (-0500) Subject: c++: Fix ICE with variadic concepts and aliases [PR93907] X-Git-Tag: upstream/12.2.0~12098 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=71a8040716c1342547a19c25bd0203ac29258ef3;p=platform%2Fupstream%2Fgcc.git c++: Fix ICE with variadic concepts and aliases [PR93907] This patch (naively) extends the PR93907 fix to also apply to variadic concepts invoked with a type argument pack. Without this, we ICE on the below testcase (a variadic version of concepts-using2.C) in the same manner as we used to on concepts-using2.C before r10-7133. gcc/cp/ChangeLog: PR c++/93907 * constraint.cc (tsubst_parameter_mapping): Also canonicalize the type arguments of a TYPE_ARGUMENT_PACk. gcc/testsuite/ChangeLog: PR c++/93907 * g++.dg/cpp2a/concepts-using3.C: New test, based off of concepts-using2.C. --- diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index b6f6f0d..c871a8a 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -2252,6 +2252,16 @@ tsubst_parameter_mapping (tree map, tree args, subst_info info) new_arg = tsubst_template_arg (arg, args, complain, in_decl); if (TYPE_P (new_arg)) new_arg = canonicalize_type_argument (new_arg, complain); + if (TREE_CODE (new_arg) == TYPE_ARGUMENT_PACK) + { + tree pack_args = ARGUMENT_PACK_ARGS (new_arg); + for (int i = 0; i < TREE_VEC_LENGTH (pack_args); i++) + { + tree& pack_arg = TREE_VEC_ELT (pack_args, i); + if (TYPE_P (pack_arg)) + pack_arg = canonicalize_type_argument (pack_arg, complain); + } + } } if (new_arg == error_mark_node) return error_mark_node; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-using3.C b/gcc/testsuite/g++.dg/cpp2a/concepts-using3.C new file mode 100644 index 0000000..2c8ad40 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-using3.C @@ -0,0 +1,52 @@ +// PR c++/93907 +// { dg-options -std=gnu++20 } + +// This testcase is a variadic version of concepts-using2.C; the only +// difference is that 'cd' and 'ce' are now variadic concepts. + +template struct c { + static constexpr int d = a; + typedef c e; +}; +template struct f; +template using g = typename f::e; +struct b; +template struct f { using e = b; }; +template struct m { typedef g aj; }; +template struct n { typedef typename m::aj e; }; +template using an = typename n::e; +template constexpr bool ao = c::d; +template constexpr bool i = c<1>::d; +template concept bb = i; +#ifdef __SIZEOF_INT128__ +using cc = __int128; +#else +using cc = long long; +#endif +template concept cd = bb; +template concept ce = requires { requires cd; }; +template concept h = ce; +template concept l = h; +template concept cl = ao; +template concept cp = requires(b j) { + requires h>; +}; +struct o { + template requires cp auto operator()(b) {} +}; +template using cm = decltype(o{}(b())); +template concept ct = l; +template concept dd = ct>; +template concept de = dd; +struct { + template void operator()(da, b); +} di; +struct p { + void begin(); +}; +template using df = p; +template void q() { + df k; + int d; + di(k, d); +}