+2019-07-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/90098 - partial specialization and class non-type parms.
+ PR c++/90099
+ PR c++/90101
+ * call.c (build_converted_constant_expr_internal): Don't copy.
+ * pt.c (process_partial_specialization): Allow VIEW_CONVERT_EXPR
+ around class non-type parameter.
+ (unify) [TEMPLATE_PARM_INDEX]: Ignore cv-quals.
+
2019-07-16 Jason Merrill <jason@redhat.com>
* parser.c (make_location): Add overload taking cp_lexer* as last
if (conv)
{
+ /* Don't copy a class in a template. */
+ if (CLASS_TYPE_P (type) && conv->kind == ck_rvalue
+ && processing_template_decl)
+ conv = next_conversion (conv);
+
conv->check_narrowing = true;
conv->check_narrowing_const_only = true;
expr = convert_like (conv, expr, complain);
simple identifier' condition and also the `specialized
non-type argument' bit. */
&& TREE_CODE (arg) != TEMPLATE_PARM_INDEX
- && !(REFERENCE_REF_P (arg)
+ && !((REFERENCE_REF_P (arg)
+ || TREE_CODE (arg) == VIEW_CONVERT_EXPR)
&& TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_PARM_INDEX))
{
if ((!packed_args && tpd.arg_uses_template_parms[i])
/* Template-parameter dependent expression. Just accept it for now.
It will later be processed in convert_template_argument. */
;
- else if (same_type_p (non_reference (TREE_TYPE (arg)),
- non_reference (tparm)))
- /* OK */;
+ else if (same_type_ignoring_top_level_qualifiers_p
+ (non_reference (TREE_TYPE (arg)),
+ non_reference (tparm)))
+ /* OK. Ignore top-level quals here because a class-type template
+ parameter object is const. */;
else if ((strict & UNIFY_ALLOW_INTEGER)
&& CP_INTEGRAL_TYPE_P (tparm))
/* Convert the ARG to the type of PARM; the deduced non-type
--- /dev/null
+// PR c++/90101
+// { dg-do compile { target c++2a } }
+
+template<typename List>
+struct A;
+
+template<template<auto...> typename List>
+struct A<List<>> {};
+
+template<template<auto...> typename List, auto V>
+struct A<List<V>> {};
+
+template<auto>
+struct B {};
+
+struct X { int value; };
+A<B<X{1}>> a2;
--- /dev/null
+// PR c++/90099
+// { dg-do compile { target c++2a } }
+
+struct Unit {
+ int value;
+ // auto operator<=>(const Unit&) = default;
+};
+
+template<Unit U, typename... Ts>
+struct X {};
+
+template<Unit U, typename T, typename... Rest>
+struct X<U, T, Rest...> {};
--- /dev/null
+// PR c++/90098
+// { dg-do compile { target c++2a } }
+
+struct A {
+ int value;
+ // auto operator<=>(const A&) = default;
+};
+
+template<A... Us>
+struct Z {};
+
+template<A V, A... Rest>
+struct Z<V, Rest...> {};