This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch: fix crash with -fprofile-arcs


/* { dg-do compile } */
/* { dg-options "-fprofile-arcs" } */
#include <setjmp.h>
int foo (jmp_buf buf) { longjmp(buf, 1); }

On Monday, December 9, 2002, at 11:25  AM, Richard Henderson wrote:
It seems the block that calls longjmp has no successors, and the code
in profile.c is not expecting that.  Could somebody clarify which code
is right?
Before the invocation of the profiling routines, no successors is correct.
During the invocation of the profiling routines, however, we add fake
edges from calls to the exit block. I would not expect this to change
for a noreturn function like longjmp.

So I guess the quesion is "where did you get this null, exactly?"
The block has no successors, but the longjmp call is not marked NORETURN,
so need_fake_edge_p thinks we need to execute the special case at the
beginning of flow_call_edges_add. This doesn't allow for bb->succ==0.
I don't understand why the longjmp call doesn't get marked NORETURN,
but expand_call goes to considerable lengths to handle longjmp separately,
and I assume there's a reason for that... The patch here just checks
for the failing case in flow_call_edges_add (the necessary fake edge is
added later by add_noreturn_fake_exit_edges, which looks for bb->succ==0
rather than NORETURN). Bootstrapped and tested on Darwin.

2002-12-11 Dale Johannesen <dalej@apple.com>

* cfganal.c (flow_call_edges_add): Handle longjmp in last block.

Index: cfganal.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfganal.c,v
retrieving revision 1.30
diff -u -d -b -w -c -3 -p -r1.30 cfganal.c
cvs server: conflicting specifications of output style
*** cfganal.c 11 Oct 2002 21:09:59 -0000 1.30
--- cfganal.c 11 Dec 2002 18:38:59 -0000
*************** flow_call_edges_add (blocks)
*** 309,314 ****
--- 309,319 ----
basic_block bb = EXIT_BLOCK_PTR->prev_bb;
rtx insn = bb->end;

+ /* When this block ends with a longjmp call, bb->succ will be null,
+ yet the call is not marked NORETURN. This case will be handled
+ later; avoid a crash for now. */
+ if (bb->succ)
+ {
/* Back up past insns that must be kept in the same block as a call. */
while (insn != bb->head
&& keep_with_call_p (insn))
*************** flow_call_edges_add (blocks)
*** 324,329 ****
--- 329,335 ----

insert_insn_on_edge (gen_rtx_USE (VOIDmode, const0_rtx), e);
commit_edge_insertions ();
+ }
}
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]