toir.cc (pop_label): Only queue labels in a vector.
authorRichard Biener <rguenther@suse.de>
Tue, 11 Jun 2019 08:30:47 +0000 (08:30 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 11 Jun 2019 08:30:47 +0000 (08:30 +0000)
2019-06-11  Richard Biener  <rguenthe@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.

From-SVN: r272146

gcc/d/ChangeLog
gcc/d/toir.cc

index 800dcb0abbce925962e0ae0f285d3866c26afd74..b94a903c8ad6a18b894799fd220d03d7429cd6c2 100644 (file)
@@ -1,3 +1,11 @@
+2019-06-11  Richard Biener  <rguenthe@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.
+
 2019-05-24  Nathan Sidwell  <nathan@acm.org>
 
        * types.cc (fixup_anonymous_offset): Use IDENTIFIER_ANON_P.
index 1d125b4396253c59ac66d1a9cd7f6400283a9f95..4c4d639d3b68ecd6c223e3dab7b71928e0ae3c7e 100644 (file)
@@ -65,10 +65,10 @@ pop_binding_label (Statement * const &, d_label_entry *ent, binding_level *bl)
 }
 
 /* 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_entry *ent, tree block)
       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
     {