diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-04-13 16:45:46 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-04-13 16:45:46 +0200 |
commit | 3eddc1c9718c6b8264d42cda6e76a3dd9ffc93f0 (patch) | |
tree | b802aeb1353a87fecdf39a536b7332d0ff55e3ff /gcc | |
parent | 9d4099343ab2eec82ddb4faff48b6e04fed5519c (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/decl.c | 58 |
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; } } |