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>
PR c++/70615
......
......@@ -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;
}
}
......
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