Commit 3eddc1c9 by Jakub Jelinek Committed by Jakub Jelinek

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
parent 9d409934
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> 2016-04-13 Jason Merrill <jason@redhat.com>
PR c++/70615 PR c++/70615
......
...@@ -368,33 +368,61 @@ pop_label (tree label, tree old_value) ...@@ -368,33 +368,61 @@ pop_label (tree label, tree old_value)
SET_IDENTIFIER_LABEL_VALUE (DECL_NAME (label), old_value); SET_IDENTIFIER_LABEL_VALUE (DECL_NAME (label), old_value);
} }
/* At the end of a function, all labels declared within the function /* Push all named labels into a vector, so that we can sort it on DECL_UID
go out of scope. BLOCK is the top-level block for the to avoid code generation differences. */
function. */
int 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; labels.quick_push (slot);
return 1;
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); /* 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 static void
pop_labels (tree block) pop_labels (tree block)
{ {
if (named_labels) 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; named_labels = NULL;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment