This introduces an early exit test to most_specialized_partial_spec for the common case where we have no partial specializations, which allows us to avoid some unnecessary work. In passing, clean the function up a bit.
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk? gcc/cp/ChangeLog: * pt.cc (most_specialized_partial_spec): Exit early when DECL_TEMPLATE_SPECIALIZATIONS is empty. Move local variable declarations closer to their first use. Remove redundant flag_concepts test. Remove redundant forward declaration. --- gcc/cp/pt.cc | 45 +++++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index fe7e809fc2d..497a18ef728 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -187,7 +187,6 @@ static int unify_pack_expansion (tree, tree, tree, static tree copy_template_args (tree); static tree tsubst_template_parms (tree, tree, tsubst_flags_t); static void tsubst_each_template_parm_constraints (tree, tree, tsubst_flags_t); -tree most_specialized_partial_spec (tree, tsubst_flags_t); static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int); static tree tsubst_arg_types (tree, tree, tree, tsubst_flags_t, tree); static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree); @@ -25756,15 +25755,7 @@ most_general_template (tree decl) tree most_specialized_partial_spec (tree target, tsubst_flags_t complain) { - tree list = NULL_TREE; - tree t; - tree champ; - int fate; - bool ambiguous_p; - tree outer_args = NULL_TREE; - tree tmpl, args; - - tree decl; + tree tmpl, args, decl; if (TYPE_P (target)) { tree tinfo = CLASSTYPE_TEMPLATE_INFO (target); @@ -25788,13 +25779,18 @@ most_specialized_partial_spec (tree target, tsubst_flags_t complain) else gcc_unreachable (); + tree main_tmpl = most_general_template (tmpl); + tree specs = DECL_TEMPLATE_SPECIALIZATIONS (main_tmpl); + if (!specs) + /* There are no partial specializations of this template. */ + return NULL_TREE; + push_access_scope_guard pas (decl); deferring_access_check_sentinel acs (dk_no_deferred); - tree main_tmpl = most_general_template (tmpl); - /* For determining which partial specialization to use, only the innermost args are interesting. */ + tree outer_args = NULL_TREE; if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args)) { outer_args = strip_innermost_template_args (args, 1); @@ -25806,7 +25802,8 @@ most_specialized_partial_spec (tree target, tsubst_flags_t complain) fully resolve everything. */ processing_template_decl_sentinel ptds; - for (t = DECL_TEMPLATE_SPECIALIZATIONS (main_tmpl); t; t = TREE_CHAIN (t)) + tree list = NULL_TREE; + for (tree t = specs; t; t = TREE_CHAIN (t)) { const tree ospec_tmpl = TREE_VALUE (t); @@ -25829,10 +25826,8 @@ most_specialized_partial_spec (tree target, tsubst_flags_t complain) if (outer_args) spec_args = add_to_template_args (outer_args, spec_args); - /* Keep the candidate only if the constraints are satisfied, - or if we're not compiling with concepts. */ - if (!flag_concepts - || constraints_satisfied_p (ospec_tmpl, spec_args)) + /* Keep the candidate only if the constraints are satisfied. */ + if (constraints_satisfied_p (ospec_tmpl, spec_args)) { list = tree_cons (spec_args, ospec_tmpl, list); TREE_TYPE (list) = TREE_TYPE (t); @@ -25843,13 +25838,11 @@ most_specialized_partial_spec (tree target, tsubst_flags_t complain) if (! list) return NULL_TREE; - ambiguous_p = false; - t = list; - champ = t; - t = TREE_CHAIN (t); - for (; t; t = TREE_CHAIN (t)) + tree champ = list; + bool ambiguous_p = false; + for (tree t = TREE_CHAIN (list); t; t = TREE_CHAIN (t)) { - fate = more_specialized_partial_spec (tmpl, champ, t); + int fate = more_specialized_partial_spec (tmpl, champ, t); if (fate == 1) ; else @@ -25868,9 +25861,9 @@ most_specialized_partial_spec (tree target, tsubst_flags_t complain) } if (!ambiguous_p) - for (t = list; t && t != champ; t = TREE_CHAIN (t)) + for (tree t = list; t && t != champ; t = TREE_CHAIN (t)) { - fate = more_specialized_partial_spec (tmpl, champ, t); + int fate = more_specialized_partial_spec (tmpl, champ, t); if (fate != 1) { ambiguous_p = true; @@ -25889,7 +25882,7 @@ most_specialized_partial_spec (tree target, tsubst_flags_t complain) else error ("ambiguous template instantiation for %q#D", target); str = ngettext ("candidate is:", "candidates are:", list_length (list)); - for (t = list; t; t = TREE_CHAIN (t)) + for (tree t = list; t; t = TREE_CHAIN (t)) { tree subst = build_tree_list (TREE_VALUE (t), TREE_PURPOSE (t)); inform (DECL_SOURCE_LOCATION (TREE_VALUE (t)), -- 2.37.2.490.g6c8e4ee870