aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-04-13 16:45:46 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2016-04-13 16:45:46 +0200
commit3eddc1c9718c6b8264d42cda6e76a3dd9ffc93f0 (patch)
treeb802aeb1353a87fecdf39a536b7332d0ff55e3ff /gcc
parent9d4099343ab2eec82ddb4faff48b6e04fed5519c (diff)
downloadgcc-3eddc1c9718c6b8264d42cda6e76a3dd9ffc93f0.zip
gcc-3eddc1c9718c6b8264d42cda6e76a3dd9ffc93f0.tar.gz
gcc-3eddc1c9718c6b8264d42cda6e76a3dd9ffc93f0.tar.bz2
re PR c++/70594 (-fcompare-debug failure)
PR c++/70594 * decl.c (pop_labels_1): Removed. (note_label, sort_labels): New functions. (pop_labels): During named_labels traversal, just push the slot pointers into a vector, then qsort it by DECL_UID and only then call pop_label and chain it into BLOCK_VARS. From-SVN: r234942
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/decl.c58
2 files changed, 52 insertions, 15 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 71538ab..4412994 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2016-04-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/70594
+ * decl.c (pop_labels_1): Removed.
+ (note_label, sort_labels): New functions.
+ (pop_labels): During named_labels traversal, just push the slot
+ pointers into a vector, then qsort it by DECL_UID and only then
+ call pop_label and chain it into BLOCK_VARS.
+
2016-04-13 Jason Merrill <jason@redhat.com>
PR c++/70615
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 9260f4c..2ac5c4b 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -368,33 +368,61 @@ pop_label (tree label, tree old_value)
SET_IDENTIFIER_LABEL_VALUE (DECL_NAME (label), old_value);
}
-/* 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. */
+/* Push all named labels into a vector, so that we can sort it on DECL_UID
+ to avoid code generation differences. */
int
-pop_labels_1 (named_label_entry **slot, tree block)
+note_label (named_label_entry **slot, vec<named_label_entry **> &labels)
{
- struct named_label_entry *ent = *slot;
-
- pop_label (ent->label_decl, NULL_TREE);
-
- /* Put the labels into the "variables" of the top-level block,
- so debugger can see them. */
- DECL_CHAIN (ent->label_decl) = BLOCK_VARS (block);
- BLOCK_VARS (block) = ent->label_decl;
+ labels.quick_push (slot);
+ return 1;
+}
- named_labels->clear_slot (slot);
+/* Helper function to sort named label entries in a vector by DECL_UID. */
- return 1;
+static int
+sort_labels (const void *a, const void *b)
+{
+ named_label_entry **slot1 = *(named_label_entry **const *) a;
+ named_label_entry **slot2 = *(named_label_entry **const *) b;
+ if (DECL_UID ((*slot1)->label_decl) < DECL_UID ((*slot2)->label_decl))
+ return -1;
+ if (DECL_UID ((*slot1)->label_decl) > DECL_UID ((*slot2)->label_decl))
+ return 1;
+ return 0;
}
+/* 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. */
+
static void
pop_labels (tree block)
{
if (named_labels)
{
- named_labels->traverse<tree, pop_labels_1> (block);
+ auto_vec<named_label_entry **, 32> labels;
+ named_label_entry **slot;
+ unsigned int i;
+
+ /* Push all the labels into a vector and sort them by DECL_UID,
+ so that gaps between DECL_UIDs don't affect code generation. */
+ labels.reserve_exact (named_labels->elements ());
+ named_labels->traverse<vec<named_label_entry **> &, note_label> (labels);
+ labels.qsort (sort_labels);
+ FOR_EACH_VEC_ELT (labels, i, slot)
+ {
+ struct named_label_entry *ent = *slot;
+
+ pop_label (ent->label_decl, NULL_TREE);
+
+ /* Put the labels into the "variables" of the top-level block,
+ so debugger can see them. */
+ DECL_CHAIN (ent->label_decl) = BLOCK_VARS (block);
+ BLOCK_VARS (block) = ent->label_decl;
+
+ named_labels->clear_slot (slot);
+ }
named_labels = NULL;
}
}