diff options
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r-- | gcc/cp/pt.c | 41 |
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. */ |