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


Reply via email to