The following fixes random debug info differences I was experiencing building the D runtime. The issue is ordering BLOCK_VARS after a hash-table traversal order which is susceptible to address-space randomization differences.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. OK for trunk and branch? Thanks, Richard. 2019-06-07 Richard Biener <rguen...@suse.de> d/90778 * toir.cc (pop_label): Only queue labels in a vector. (cmp_labels): Label decl comparator. (pop_binding_level): Pop labels in DECL_UID order to avoid debug info differences. Index: gcc/d/toir.cc =================================================================== --- gcc/d/toir.cc (revision 272037) +++ gcc/d/toir.cc (working copy) @@ -65,10 +65,10 @@ pop_binding_label (Statement * const &, } /* At the end of a function, all labels declared within the function - go out of scope. BLOCK is the top-level block for the function. */ + go out of scope. Queue them in LABELS. */ bool -pop_label (Statement * const &s, d_label_entry *ent, tree block) +pop_label (Statement * const &, d_label_entry *ent, vec<tree> &labels) { if (!ent->bc_label) { @@ -77,13 +77,10 @@ pop_label (Statement * const &s, d_label if (DECL_NAME (ent->label)) { gcc_assert (DECL_INITIAL (ent->label) != NULL_TREE); - DECL_CHAIN (ent->label) = BLOCK_VARS (block); - BLOCK_VARS (block) = ent->label; + labels.safe_push (ent->label); } } - d_function_chain->labels->remove (s); - return true; } @@ -103,6 +100,14 @@ push_binding_level (level_kind kind) current_binding_level = new_level; } +static int +cmp_labels (const void *p1, const void *p2) +{ + const tree *l1 = (const tree *)p1; + const tree *l2 = (const tree *)p2; + return DECL_UID (*l1) - DECL_UID (*l2); +} + tree pop_binding_level (void) { @@ -125,7 +130,17 @@ pop_binding_level (void) /* Pop all the labels declared in the function. */ if (d_function_chain->labels) - d_function_chain->labels->traverse<tree, &pop_label> (block); + { + auto_vec<tree> labels; + d_function_chain->labels->traverse<vec<tree> &, &pop_label> (labels); + d_function_chain->labels->empty (); + labels.qsort (cmp_labels); + for (unsigned i = 0; i < labels.length (); ++i) + { + DECL_CHAIN (labels[i]) = BLOCK_VARS (block); + BLOCK_VARS (block) = labels[i]; + } + } } else {