Hello,
I am facing some trouble with the following code (reduced with c-reduce):
fn1 (ip)
int *ip;
{
int x = 0;
int *a;
base:
x++;
if (x == 4)
return;
*a++ = 1;
goto *&&base + *ip++;
}
The problems lies in the label base.
Label base is added to the forced_labels list, but it is unfortunately deleted
by cfg_layout_merge_blocks since it's the first insn of a basic block being
merged into another.
This breaks dwarf information generation because it calls
maybe_record_trace_start with all the forced labels (dwarf2cfi.c in
create_trace_edges) and it expects a trace to exist starting at each of the
forced labels in the list (ensured by the gcc_assert(ti != NULL) in
maybe_record_trace_start). Even though the label does exist in the forced
labels list (now as a note saying it was deleted), the label didn't trigger the
generation of a trace at this point.
The code in cfgrtl to remove the label is:
if (LABEL_P (BB_HEAD (b)))
{
delete_insn (BB_HEAD (b));
}
I was however expecting a call to can_delete_label_p in the condition, or the
removal of the label from forced_labels if it is a forced label.
Adding the condition can_delete_label_p to the code above results in a
segmentation fault during scheduling so it seems that there's some kind of
assumption regarding code_labels position in a block. The segmentation fault is
triggered at sched_get_condition_with_rev_uncached because the code_label is
passed as an argument to this function and GET_CODE (pat) == COND_EXEC
generates the seg fault.
My question is, given it is a forced label, it seems to me that we really
shouldn't delete the label. Is there a missed constraint in the condition above
and therefore some further checks in scheduling?
Paulo Matos