summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2014-06-30 15:11:14 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2014-06-30 15:11:14 +0000
commit58bc5407661dc5de05584d60feccf220a8503dd1 (patch)
treecbef86c87287d6efdc3ea30284a8b068619a5ffe
parentde56f7e447265acedf27f92ee9bcfe5585ccf49f (diff)
downloadgcc-58bc5407661dc5de05584d60feccf220a8503dd1.tar.gz
PR c++/61539
* pt.c (unify_one_argument): Type/expression mismatch just causes deduction failure. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@212154 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/pt.c5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic160.C49
3 files changed, 56 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b478cf739f8..f1212369d2f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2014-06-30 Jason Merrill <jason@redhat.com>
+ PR c++/61539
+ * pt.c (unify_one_argument): Type/expression mismatch just causes
+ deduction failure.
+
* semantics.c (simplify_aggr_init_expr): Remove remnants of
2014-04-11 change.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f0a598beff8..7f33b6d5ffa 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -16501,8 +16501,9 @@ unify_one_argument (tree tparms, tree targs, tree parm, tree arg,
maybe_adjust_types_for_deduction (strict, &parm, &arg, arg_expr);
}
else
- gcc_assert ((TYPE_P (parm) || TREE_CODE (parm) == TEMPLATE_DECL)
- == (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL));
+ if ((TYPE_P (parm) || TREE_CODE (parm) == TEMPLATE_DECL)
+ != (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL))
+ return unify_template_argument_mismatch (explain_p, parm, arg);
/* For deduction from an init-list we need the actual list. */
if (arg_expr && BRACE_ENCLOSED_INITIALIZER_P (arg_expr))
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic160.C b/gcc/testsuite/g++.dg/cpp0x/variadic160.C
new file mode 100644
index 00000000000..20fcd5b4fe7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic160.C
@@ -0,0 +1,49 @@
+// PR c++/61539
+// { dg-do compile { target c++11 } }
+
+template <typename _CharT> class A;
+template <typename> class B;
+template <class charT> class C;
+template <> class C<char>
+{
+ virtual void xparse (int &, const B<A<char> > &) const;
+};
+template <class T, class charT = char> class G : C<charT>
+{
+public:
+ G (void *) {}
+ void default_value (const T &);
+ void xparse (int &, const B<A<charT> > &) const;
+};
+template <class T, class charT>
+void validate (int &, const B<A<charT> > &, T *, int);
+template <class T, class charT>
+void G<T, charT>::xparse (int &p1, const B<A<charT> > &p2) const
+{
+ validate (p1, p2, (T *)0, 0);
+}
+template <class T> G<T> *value (T *) { return new G<T>(0); }
+namespace Eigen
+{
+template <typename T> struct D;
+template <typename, int, int, int = 0, int = 0, int = 0 > class F;
+template <typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows,
+ int _MaxCols>
+struct D<F<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
+{
+ typedef _Scalar Scalar;
+};
+template <typename, int, int, int, int, int _MaxCols> class F
+{
+public:
+ typedef typename Eigen::D<F>::Scalar Scalar;
+ F (const Scalar &, const Scalar &, const Scalar &);
+};
+template <class... T>
+void validate (int &, const B<A<char> > &, Eigen::F<T...> *);
+}
+int main (int, char *[])
+{
+ Eigen::F<double, 3, 1> a (0, 0, 0);
+ value (&a)->default_value (Eigen::F<double, 3, 1>(0, 0, 0));
+}