aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r--gcc/cp/pt.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 3069c28181b..3bb491860c7 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -13248,7 +13248,12 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
--c_inhibit_evaluation_warnings;
if (TREE_CODE (expanded) == TREE_VEC)
- len = TREE_VEC_LENGTH (expanded);
+ {
+ len = TREE_VEC_LENGTH (expanded);
+ /* Set TREE_USED for the benefit of -Wunused. */
+ for (int i = 0; i < len; i++)
+ TREE_USED (TREE_VEC_ELT (expanded, i)) = true;
+ }
if (expanded == error_mark_node)
return error_mark_node;
@@ -19472,6 +19477,38 @@ most_general_template (tree decl)
return decl;
}
+/* True iff the TEMPLATE_DECL tmpl is a partial specialization. */
+
+static bool
+partial_specialization_p (tree tmpl)
+{
+ /* Any specialization has DECL_TEMPLATE_SPECIALIZATION. */
+ if (!DECL_TEMPLATE_SPECIALIZATION (tmpl))
+ return false;
+ if (!VAR_P (DECL_TEMPLATE_RESULT (tmpl)))
+ return false;
+ tree t = DECL_TI_TEMPLATE (tmpl);
+ /* A specialization that fully specializes one of the containing classes is
+ not a partial specialization. */
+ return (list_length (DECL_TEMPLATE_PARMS (tmpl))
+ == list_length (DECL_TEMPLATE_PARMS (t)));
+}
+
+/* If TMPL is a partial specialization, return the arguments for its primary
+ template. */
+
+static tree
+impartial_args (tree tmpl, tree args)
+{
+ if (!partial_specialization_p (tmpl))
+ return args;
+
+ /* If TMPL is a partial specialization, we need to substitute to get
+ the args for the primary template. */
+ return tsubst_template_args (DECL_TI_ARGS (tmpl), args,
+ tf_warning_or_error, tmpl);
+}
+
/* Return the most specialized of the template partial specializations
which can produce TARGET, a specialization of some class or variable
template. The value returned is actually a TREE_LIST; the TREE_VALUE is
@@ -20286,7 +20323,7 @@ instantiate_decl (tree d, int defer_ok,
return d;
gen_tmpl = most_general_template (tmpl);
- gen_args = DECL_TI_ARGS (d);
+ gen_args = impartial_args (tmpl, DECL_TI_ARGS (d));
if (tmpl != gen_tmpl)
/* We should already have the extra args. */