diff options
author | Jason Merrill <jason@redhat.com> | 2017-06-16 22:27:59 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2017-06-16 22:27:59 -0400 |
commit | 3da557ec145823c3f51ff3fa7c619d0064134800 (patch) | |
tree | a47647c0daf7d0a6e9c7479a928f0e1cfcfb75e6 /gcc | |
parent | 157420b4bd936f18b64d8143a6b3f32f89689412 (diff) | |
download | gcc-3da557ec145823c3f51ff3fa7c619d0064134800.zip gcc-3da557ec145823c3f51ff3fa7c619d0064134800.tar.gz gcc-3da557ec145823c3f51ff3fa7c619d0064134800.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 34 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/partial-specialization7.C | 40 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/partial5.C | 2 |
4 files changed, 63 insertions, 17 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 330f0f2..2d47d7b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 0a58163..d2b91b2 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 0000000..aa42191 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial-specialization7.C @@ -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; +} diff --git a/gcc/testsuite/g++.dg/template/partial5.C b/gcc/testsuite/g++.dg/template/partial5.C index 1b56fb3..ee45a93 100644 --- a/gcc/testsuite/g++.dg/template/partial5.C +++ b/gcc/testsuite/g++.dg/template/partial5.C @@ -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> |