From: Jason Merrill Date: Sat, 17 Jun 2017 02:27:59 +0000 (-0400) Subject: PR c++/81102 - Wrong error with partial specialization. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3da557ec145823c3f51ff3fa7c619d0064134800;p=gcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 330f0f205a0..2d47d7b4a7f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2017-06-16 Jason Merrill + 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. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 0a581630347..d2b91b24356 100644 --- a/gcc/cp/pt.c +++ b/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)); diff --git a/gcc/testsuite/g++.dg/template/partial-specialization7.C b/gcc/testsuite/g++.dg/template/partial-specialization7.C new file mode 100644 index 00000000000..aa42191e178 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial-specialization7.C @@ -0,0 +1,40 @@ +// PR c++/81102 + +template +struct HelperWrapper; + +// [...] + +template +struct HelperWrapper +{ + static inline int WrapFuncT(const int) + { + return 0; // Changed + } +}; + +// Unary +template +struct HelperWrapper +{ + static inline int WrapFuncT(const int) + { + return 1; // Changed + } +}; + +// Binary +template +struct HelperWrapper +{ + static inline int WrapFuncT(const int) + { + return 2; // Changed + } +}; + +int main() +{ + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/partial5.C b/gcc/testsuite/g++.dg/template/partial5.C index 1b56fb39fa1..ee45a936a0c 100644 --- a/gcc/testsuite/g++.dg/template/partial5.C +++ b/gcc/testsuite/g++.dg/template/partial5.C @@ -14,7 +14,7 @@ template struct Y { }; template -struct Y { }; // { dg-error "" } +struct Y { }; // { dg-error "" "" { target { ! c++1z } } } template