https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63307
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Igor Zamyatin from comment #1) > Would like to ask here first - will something like following be ok: > +typedef struct > +{ > + tree parm; > + tree arg; > +} decl_pair; > + > +static vec<decl_pair> vec_arglist; Just use struct cilk_decl_pair, no need for typedef in C++ here, and try to avoid ODR issues. Also, why a static variable? Then you supposedly would need to GTY handle it etc., which is IMHO undesirable. > static bool > wrapper_parm_cb (const void *key0, void **val0, void *data) > { > - struct wrapper_data *wd = (struct wrapper_data *) data; > tree arg = * (tree *)&key0; > tree val = (tree)*val0; > tree parm; > + decl_pair dp; > > if (val == error_mark_node || val == arg) > return true; > @@ -370,25 +379,48 @@ wrapper_parm_cb (const void *key0, void **val0, void > *data) > } > else > parm = val; > - TREE_CHAIN (parm) = wd->parms; > - wd->parms = parm; > - wd->argtypes = tree_cons (NULL_TREE, TREE_TYPE (parm), wd->argtypes); > - wd->arglist = tree_cons (NULL_TREE, arg, wd->arglist); > + > + dp.parm = parm; > + dp.arg = arg; > + vec_arglist.safe_push(dp); Formatting, missing space before (. But more importantly, the diagnostics still be in random order. So, I'd strongly suggest to move also the diagnostics and ADDR_EXPR building etc. into a loop that walks the sorted vector. > return true; > } > > /* This function is used to build a wrapper of a certain type. */ > > +static int > +compare_decls (const void *a, const void *b) > +{ > + const decl_pair* t1 = (const decl_pair*) a; > + const decl_pair* t2 = (const decl_pair*) b; > + > + return DECL_UID(t1->arg) > DECL_UID(t2->arg); Formatting. Space before *, not after, space before (, indentation 2 columns rather than 4. > +} > + > static void > build_wrapper_type (struct wrapper_data *wd) > { > + unsigned int j; > + decl_pair * c; > wd->arglist = NULL_TREE; > wd->parms = NULL_TREE; > wd->argtypes = void_list_node; > > - pointer_map_traverse (wd->decl_map, wrapper_parm_cb, wd); > + vec_arglist.create (0); > + pointer_map_traverse (wd->decl_map, wrapper_parm_cb, NULL); > gcc_assert (wd->type != CILK_BLOCK_FOR); > > + vec_arglist.qsort(compare_decls); Formatting. > + > + FOR_EACH_VEC_ELT (vec_arglist, j, c) > + { > + TREE_CHAIN (c->parm) = wd->parms; > + wd->parms = c->parm; > + wd->argtypes = tree_cons (NULL_TREE, TREE_TYPE (c->parm), > wd->argtypes); > + wd->arglist = tree_cons (NULL_TREE, c->arg, wd->arglist); > + } As I said earlier, I'd do diagnostics and ADDR_EXPR creation in this loop too. > + vec_arglist.release(); Formatting. You could use auto_vec, perhaps with some stack allocated initial buffer if you think say 16 vector elements would be typically enough. Also, what about all the remaining 3 callbacks that create or may create decls and have the same problem? for_local_cb, wrapper_local_cb and declare_one_free_variable.