PR c++/81102 - Wrong error with partial specialization.

* pt.c (unify) [TEMPLATE_PARM_INDEX]: Strip reference when comparing
	types.  Do type deduction later.

From-SVN: r249320
This commit is contained in:
Jason Merrill 2017-06-16 22:27:59 -04:00 committed by Jason Merrill
parent 157420b4bd
commit 3da557ec14
4 changed files with 63 additions and 17 deletions

View File

@ -1,5 +1,9 @@
2017-06-16 Jason Merrill <jason@redhat.com>
PR c++/81102 - Wrong error with partial specialization.
* pt.c (unify) [TEMPLATE_PARM_INDEX]: Strip reference when comparing
types. Do type deduction later.
PR c++/80174 - ICE with partial specialization of member template.
PR c++/71747
* pt.c (get_partial_spec_bindings): Only coerce innermost args.

View File

@ -20628,18 +20628,6 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
return x;
}
if (cxx_dialect >= cxx1z
/* We deduce from array bounds in try_array_deduction. */
&& !(strict & UNIFY_ALLOW_INTEGER)
&& uses_template_parms (TREE_TYPE (parm))
&& !type_uses_auto (TREE_TYPE (parm)))
{
tree atype = TREE_TYPE (arg);
RECUR_AND_CHECK_FAILURE (tparms, targs,
TREE_TYPE (parm), atype,
UNIFY_ALLOW_NONE, explain_p);
}
/* [temp.deduct.type] If, in the declaration of a function template
with a non-type template-parameter, the non-type
template-parameter is used in an expression in the function
@ -20660,7 +20648,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
/* Template-parameter dependent expression. Just accept it for now.
It will later be processed in convert_template_argument. */
;
else if (same_type_p (TREE_TYPE (arg), tparm))
else if (same_type_p (non_reference (TREE_TYPE (arg)),
non_reference (tparm)))
/* OK */;
else if ((strict & UNIFY_ALLOW_INTEGER)
&& CP_INTEGRAL_TYPE_P (tparm))
@ -20669,9 +20658,22 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
corresponding parameter. */
arg = fold (build_nop (tparm, arg));
else if (uses_template_parms (tparm))
/* We haven't deduced the type of this parameter yet. Try again
later. */
return unify_success (explain_p);
{
/* We haven't deduced the type of this parameter yet. */
if (cxx_dialect >= cxx1z
/* We deduce from array bounds in try_array_deduction. */
&& !(strict & UNIFY_ALLOW_INTEGER))
{
/* Deduce it from the non-type argument. */
tree atype = TREE_TYPE (arg);
RECUR_AND_CHECK_FAILURE (tparms, targs,
tparm, atype,
UNIFY_ALLOW_NONE, explain_p);
}
else
/* Try again later. */
return unify_success (explain_p);
}
else
return unify_type_mismatch (explain_p, tparm, TREE_TYPE (arg));

View File

@ -0,0 +1,40 @@
// PR c++/81102
template <typename FuncSig, FuncSig f>
struct HelperWrapper;
// [...]
template <typename Ret, Ret (&Func)()>
struct HelperWrapper<Ret (&)(), Func>
{
static inline int WrapFuncT(const int)
{
return 0; // Changed
}
};
// Unary
template <typename Ret, typename Arg1, Ret (&Func)(Arg1)>
struct HelperWrapper<Ret (&)(Arg1), Func>
{
static inline int WrapFuncT(const int)
{
return 1; // Changed
}
};
// Binary
template <typename Ret, typename Arg1, typename Arg2, Ret (&Func)(Arg1, Arg2)>
struct HelperWrapper<Ret (&)(Arg1, Arg2), Func>
{
static inline int WrapFuncT(const int)
{
return 2; // Changed
}
};
int main()
{
return 0;
}

View File

@ -14,7 +14,7 @@ template<typename T, typename T::foo V>
struct Y { };
template<typename T, typename U, U v>
struct Y<T, v> { }; // { dg-error "" }
struct Y<T, v> { }; // { dg-error "" "" { target { ! c++1z } } }
template<typename T, T V>