summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-06 15:45:10 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-06 15:45:10 +0000
commitca5518fc78feb98269f7089a2053f2c53e20da5a (patch)
tree7e5d952e473656b625d4c3337c1c40088b94a970
parent7dbc9f4915d91f95a8e2f5f4b8e12e2be4de0175 (diff)
downloadgcc-ca5518fc78feb98269f7089a2053f2c53e20da5a.tar.gz
PR c++/53862
* pt.c (tsubst_arg_types): Add "end" parameter. (check_undeduced_parms): Use it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@189334 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/pt.c22
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic134.C17
4 files changed, 35 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0bd2c77513d..f4075392445 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2012-07-06 Jason Merrill <jason@redhat.com>
+ PR c++/53862
+ * pt.c (tsubst_arg_types): Add "end" parameter.
+ (check_undeduced_parms): Use it.
+
* cp-tree.h (DECL_DECLARES_TYPE_P): Check DECL_TYPE_TEMPLATE_P.
PR c++/53858
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index df5d1f68b86..72b0c4f18b2 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -171,7 +171,7 @@ static tree tsubst_template_parms (tree, tree, tsubst_flags_t);
static void regenerate_decl_from_template (tree, tree);
static tree most_specialized_class (tree, tree, tsubst_flags_t);
static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int);
-static tree tsubst_arg_types (tree, tree, tsubst_flags_t, tree);
+static tree tsubst_arg_types (tree, tree, tree, tsubst_flags_t, tree);
static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree);
static bool check_specialization_scope (void);
static tree process_partial_specialization (tree);
@@ -10500,11 +10500,14 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
return r;
}
-/* Substitute into the ARG_TYPES of a function type. */
+/* Substitute into the ARG_TYPES of a function type.
+ If END is a TREE_CHAIN, leave it and any following types
+ un-substituted. */
static tree
tsubst_arg_types (tree arg_types,
tree args,
+ tree end,
tsubst_flags_t complain,
tree in_decl)
{
@@ -10514,11 +10517,11 @@ tsubst_arg_types (tree arg_types,
tree expanded_args = NULL_TREE;
tree default_arg;
- if (!arg_types || arg_types == void_list_node)
+ if (!arg_types || arg_types == void_list_node || arg_types == end)
return arg_types;
remaining_arg_types = tsubst_arg_types (TREE_CHAIN (arg_types),
- args, complain, in_decl);
+ args, end, complain, in_decl);
if (remaining_arg_types == error_mark_node)
return error_mark_node;
@@ -10643,7 +10646,7 @@ tsubst_function_type (tree t,
}
/* Substitute the argument types. */
- arg_types = tsubst_arg_types (TYPE_ARG_TYPES (t), args,
+ arg_types = tsubst_arg_types (TYPE_ARG_TYPES (t), args, NULL_TREE,
complain, in_decl);
if (arg_types == error_mark_node)
return error_mark_node;
@@ -16757,12 +16760,9 @@ check_undeduced_parms (tree targs, tree args, tree end)
}
if (found)
{
- for (; args != end; args = TREE_CHAIN (args))
- {
- tree substed = tsubst (TREE_VALUE (args), targs, tf_none, NULL_TREE);
- if (substed == error_mark_node)
- return true;
- }
+ tree substed = tsubst_arg_types (args, targs, end, tf_none, NULL_TREE);
+ if (substed == error_mark_node)
+ return true;
}
return false;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 18187f1a60d..0e79dc33fb7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2012-07-06 Jason Merrill <jason@redhat.com>
+ PR c++/53862
+ * g++.dg/cpp0x/variadic134.C: New.
+
PR c++/53858
* g++.dg/cpp0x/alias-decl-20.C: New.
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic134.C b/gcc/testsuite/g++.dg/cpp0x/variadic134.C
new file mode 100644
index 00000000000..d4181b02c8e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic134.C
@@ -0,0 +1,17 @@
+// PR c++/53862
+// { dg-do compile { target c++11 } }
+
+typedef unsigned long size_t;
+
+template<typename> struct is_scalar { static const bool value = true; };
+template<bool, typename T> struct enable_if { typedef T type; };
+
+template <size_t N, typename... Args>
+void f(Args...) {}
+
+template <size_t N, typename T, typename... Args>
+typename enable_if<is_scalar<T>::value, void>::type f(T, Args...) {}
+
+int main() {
+ f<1>(1);
+}