From 3eddc1c9718c6b8264d42cda6e76a3dd9ffc93f0 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 13 Apr 2016 16:45:46 +0200 Subject: 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 --- gcc/cp/ChangeLog | 9 +++++++++ gcc/cp/decl.c | 58 +++++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 52 insertions(+), 15 deletions(-) (limited to 'gcc') 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 + + 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 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 &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 (block); + auto_vec 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 &, 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; } } -- cgit v1.1