Commit bde31a76 by Jason Merrill

c++: Fix ICE with concepts and aliases [PR93907].

The problem here was that we were checking satisfaction once with 'e', a
typedef of 'void', and another time with 'void' directly, and treated them
as different for hashing based on the assumption that
canonicalize_type_argument would have already removed a typedef that wasn't
a complex dependent alias.  But that wasn't happening here, so let's add a
call.

gcc/cp/ChangeLog
2020-03-11  Jason Merrill  <jason@redhat.com>

	PR c++/93907
	* constraint.cc (tsubst_parameter_mapping): Canonicalize type
	argument.
parent 7eb5be6a
2020-03-11 Jason Merrill <jason@redhat.com>
PR c++/93907
* constraint.cc (tsubst_parameter_mapping): Canonicalize type
argument.
2020-03-11 Marek Polacek <polacek@redhat.com>
Jason Merrill <jason@redhat.com>
......
......@@ -2232,7 +2232,11 @@ tsubst_parameter_mapping (tree map, tree args, subst_info info)
else if (ARGUMENT_PACK_P (arg))
new_arg = tsubst_argument_pack (arg, args, complain, in_decl);
if (!new_arg)
{
new_arg = tsubst_template_arg (arg, args, complain, in_decl);
if (TYPE_P (new_arg))
new_arg = canonicalize_type_argument (new_arg, complain);
}
if (new_arg == error_mark_node)
return error_mark_node;
......
......@@ -7016,6 +7016,7 @@ extern tree resolve_nondeduced_context_or_error (tree, tsubst_flags_t);
extern hashval_t iterative_hash_template_arg (tree arg, hashval_t val);
extern tree coerce_template_parms (tree, tree, tree);
extern tree coerce_template_parms (tree, tree, tree, tsubst_flags_t);
extern tree canonicalize_type_argument (tree, tsubst_flags_t);
extern void register_local_specialization (tree, tree);
extern tree retrieve_local_specialization (tree);
extern tree extract_fnparm_pack (tree, tree *);
......
......@@ -7943,7 +7943,7 @@ template_template_parm_bindings_ok_p (tree tparms, tree targs)
/* Since type attributes aren't mangled, we need to strip them from
template type arguments. */
static tree
tree
canonicalize_type_argument (tree arg, tsubst_flags_t complain)
{
if (!arg || arg == error_mark_node || arg == TYPE_CANONICAL (arg))
......
// PR c++/93907
// { dg-options -std=gnu++20 }
template <int a> struct c {
static constexpr int d = a;
typedef c e;
};
template <typename> struct f;
template <typename b> using g = typename f<b>::e;
struct b;
template <typename b> struct f { using e = b; };
template <typename ai> struct m { typedef g<ai> aj; };
template <typename b> class n { typedef typename m<b>::aj e; };
template <typename b> using an = typename n<b>::e;
template <typename> constexpr bool ao = c<true>::d;
template <typename> constexpr bool i = c<1>::d;
template <typename> concept bb = i<b>;
using cc = __int128;
template <typename> concept cd = bb<cc>;
template <typename bt> concept ce = requires { requires cd<bt>; };
template <typename bt> concept h = ce<bt>;
template <typename bt> concept l = h<bt>;
template <typename> concept cl = ao<b>;
template <typename b> concept cp = requires(b j) {
requires h<an<decltype(j.begin())>>;
};
struct o {
template <cl b> requires cp<b> auto operator()(b) {}
};
template <typename b> using cm = decltype(o{}(b()));
template <typename bt> concept ct = l<bt>;
template <typename da> concept dd = ct<cm<da>>;
template <typename da> concept de = dd<da>;
struct {
template <de da, typename b> void operator()(da, b);
} di;
class p {
void begin();
};
template <typename> using df = p;
template <int> void q() {
df<int> k;
int d;
di(k, d);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment