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:
parent
157420b4bd
commit
3da557ec14
@ -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.
|
||||
|
34
gcc/cp/pt.c
34
gcc/cp/pt.c
@ -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));
|
||||
|
||||
|
40
gcc/testsuite/g++.dg/template/partial-specialization7.C
Normal file
40
gcc/testsuite/g++.dg/template/partial-specialization7.C
Normal 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;
|
||||
}
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user