emit_insn (targetm.gen_nonlocal_goto (value, lab, stack, fp));
else
{
- lab = copy_to_reg (lab);
-
emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
+ lab = copy_to_reg (lab);
+
/* Restore the frame pointer and stack pointer. We must use a
temporary since the setjmp buffer may be a local. */
fp = copy_to_reg (fp);
emit_stack_restore (SAVE_NONLOCAL, stack);
+
+ /* Ensure the frame pointer move is not optimized. */
+ emit_insn (gen_blockage ());
+ emit_clobber (hard_frame_pointer_rtx);
+ emit_clobber (frame_pointer_rtx);
emit_move_insn (hard_frame_pointer_rtx, fp);
emit_use (hard_frame_pointer_rtx);
emit_insn (targetm.gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
else
{
- r_label = copy_to_reg (r_label);
-
emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
+ r_label = copy_to_reg (r_label);
+
/* Restore the frame pointer and stack pointer. We must use a
temporary since the setjmp buffer may be a local. */
r_fp = copy_to_reg (r_fp);
emit_stack_restore (SAVE_NONLOCAL, r_sp);
+
+ /* Ensure the frame pointer move is not optimized. */
+ emit_insn (gen_blockage ());
+ emit_clobber (hard_frame_pointer_rtx);
+ emit_clobber (frame_pointer_rtx);
emit_move_insn (hard_frame_pointer_rtx, r_fp);
/* USE of hard_frame_pointer_rtx added for consistency;
__attribute ((noinline)) void
broken_longjmp (void *p)
{
- void *buf[5];
+ void *buf[32];
__builtin_memcpy (buf, p, 5 * sizeof (void*));
/* Corrupts stack pointer... */
__builtin_longjmp (buf, 1);
}
-__attribute ((noipa)) __UINTPTR_TYPE__
-foo (void *p)
-{
- return (__UINTPTR_TYPE__) p;
-}
-
-__attribute ((noipa)) void
-bar (void *p)
-{
- asm volatile ("" : : "r" (p));
-}
-
volatile int x = 0;
-void *volatile p;
-void *volatile q;
+char *volatile p;
+char *volatile q;
int
main ()
{
void *buf[5];
- struct __attribute__((aligned (32))) S { int a[4]; } s;
- bar (&s);
p = __builtin_alloca (x);
+ q = __builtin_alloca (x);
if (!__builtin_setjmp (buf))
broken_longjmp (buf);
+ /* Compute expected next alloca offset - some targets don't align properly
+ and allocate too much. */
+ p = q + (q - p);
+
/* Fails if stack pointer corrupted. */
- q = __builtin_alloca (x);
- if (foo (p) < foo (q))
- {
- if (foo (q) - foo (p) >= 1024)
- abort ();
- }
- else if (foo (p) - foo (q) >= 1024)
+ if (p != __builtin_alloca (x))
abort ();
return 0;