From 97268c374a348a60c53366a4bee67626c840e4a1 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 4 May 2020 09:49:52 -0700 Subject: [PATCH] c++: Simplify process_template_parm Process_template_parm ends up walking the parameter list twice. There's not need to do this. Just rember the final node and modify its CHAIN directly. Also comment on why end_template_parm_list does a pop and a push, rather than modifying the header in place. pt.c (process_template_parm): Don't walk the template list twice, remember the final node instead. (end_template_parm_list): Refactor. Comment on why we do a pop and a push. --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/pt.c | 47 ++++++++++++++++++++++++++--------------------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3d5f273477f..334899d49fb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2020-05-04 Nathan Sidwell + pt.c (process_template_parm): Don't walk the template list twice, + remember the final node instead. + (end_template_parm_list): Refactor. Comment on why we do a pop + and a push. + PR c++/94827 -- don't save parms in nested requirement * constraint.cc (tsubst_nested_requirement): TYPE directly holds notmalized requirement. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 8106c25a2d9..61cb75bf801 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4496,29 +4496,27 @@ tree process_template_parm (tree list, location_t parm_loc, tree parm, bool is_non_type, bool is_parameter_pack) { - tree decl = 0; - int idx = 0; - gcc_assert (TREE_CODE (parm) == TREE_LIST); - tree defval = TREE_PURPOSE (parm); - tree constr = TREE_TYPE (parm); + tree prev = NULL_TREE; + int idx = 0; if (list) { - tree p = tree_last (list); + prev = tree_last (list); - if (p && TREE_VALUE (p) != error_mark_node) - { - p = TREE_VALUE (p); - if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL) - idx = TEMPLATE_TYPE_IDX (TREE_TYPE (p)); - else - idx = TEMPLATE_PARM_IDX (DECL_INITIAL (p)); - } + tree p = TREE_VALUE (prev); + if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL) + idx = TEMPLATE_TYPE_IDX (TREE_TYPE (p)); + else if (TREE_CODE (p) == PARM_DECL) + idx = TEMPLATE_PARM_IDX (DECL_INITIAL (p)); ++idx; } + tree decl = NULL_TREE; + tree defval = TREE_PURPOSE (parm); + tree constr = TREE_TYPE (parm); + if (is_non_type) { parm = TREE_VALUE (parm); @@ -4616,7 +4614,12 @@ process_template_parm (tree list, location_t parm_loc, tree parm, parm = build_tree_list (defval, parm); TEMPLATE_PARM_CONSTRAINTS (parm) = reqs; - return chainon (list, parm); + if (prev) + TREE_CHAIN (prev) = parm; + else + list = parm; + + return list; } /* The end of a template parameter list has been reached. Process the @@ -4627,22 +4630,24 @@ process_template_parm (tree list, location_t parm_loc, tree parm, tree end_template_parm_list (tree parms) { - int nparms; - tree parm, next; tree saved_parmlist = make_tree_vec (list_length (parms)); - /* Pop the dummy parameter level and add the real one. */ + /* Pop the dummy parameter level and add the real one. We do not + morph the dummy parameter in place, as it might have been + captured by a (nested) template-template-parm. */ current_template_parms = TREE_CHAIN (current_template_parms); current_template_parms = tree_cons (size_int (processing_template_decl), saved_parmlist, current_template_parms); - for (parm = parms, nparms = 0; parm; parm = next, nparms++) + for (unsigned ix = 0; parms; ix++) { - next = TREE_CHAIN (parm); - TREE_VEC_ELT (saved_parmlist, nparms) = parm; + tree parm = parms; + parms = TREE_CHAIN (parms); TREE_CHAIN (parm) = NULL_TREE; + + TREE_VEC_ELT (saved_parmlist, ix) = parm; } --processing_template_parmlist;