This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Problem with sibcalls
- To: gcc-patches at gcc dot gnu dot org
- Subject: Problem with sibcalls
- From: Bernd Schmidt <bernds at balti dot cygnus dot co dot uk>
- Date: Fri, 24 Mar 2000 15:17:44 +0000 (GMT)
The following program, stripped down from drivers/scsi/scsi_merge.c in a
recent 2.3 Linux kernel, will crash cc1 on i586-linux.
extern int printk(const char *fmt, ...);
void foo (int x, int y)
{
__label__ here;
here:
printk ("", &&here);
}
The instruction that pushes the address of the label is inside a
CALL_PLACEHOLDER, so we never notice that the label is used, and turn
it into a NOTE_INSN_DELETED_LABEL. This later causes mark_jump_label
to call abort.
OK to install patch and testcase?
Bernd
* jump.c (mark_all_labels): Handle CALL_PLACEHOLDERs.
Index: jump.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/jump.c,v
retrieving revision 1.113
diff -c -p -r1.113 jump.c
*** jump.c 2000/03/20 10:45:56 1.113
--- jump.c 2000/03/24 15:13:51
*************** mark_all_labels (f, cross_jump)
*** 2265,2270 ****
--- 2279,2293 ----
for (insn = f; insn; insn = NEXT_INSN (insn))
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{
+ if (GET_CODE (insn) == CALL_INSN
+ && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
+ {
+ mark_all_labels (XEXP (PATTERN (insn), 0), cross_jump);
+ mark_all_labels (XEXP (PATTERN (insn), 1), cross_jump);
+ mark_all_labels (XEXP (PATTERN (insn), 2), cross_jump);
+ continue;
+ }
+
mark_jump_label (PATTERN (insn), insn, cross_jump, 0);
if (! INSN_DELETED_P (insn) && GET_CODE (insn) == JUMP_INSN)
{