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
     {

Reply via email to