1 /* { dg-require-effective-target indirect_jumps } */
2 
3 extern void abort (void);
4 
5 __attribute ((noinline)) void
broken_longjmp(void * p)6 broken_longjmp (void *p)
7 {
8   void *buf[5];
9   __builtin_memcpy (buf, p, 5 * sizeof (void*));
10   /* Corrupts stack pointer...  */
11   __builtin_longjmp (buf, 1);
12 }
13 
14 __attribute ((noipa)) __UINTPTR_TYPE__
foo(void * p)15 foo (void *p)
16 {
17   return (__UINTPTR_TYPE__) p;
18 }
19 
20 __attribute ((noipa)) void
bar(void * p)21 bar (void *p)
22 {
23   asm volatile ("" : : "r" (p));
24 }
25 
26 volatile int x = 0;
27 void *volatile p;
28 void *volatile q;
29 
30 int
main()31 main ()
32 {
33   void *buf[5];
34   struct __attribute__((aligned (32))) S { int a[4]; } s;
35   bar (&s);
36   p = __builtin_alloca (x);
37   if (!__builtin_setjmp (buf))
38     broken_longjmp (buf);
39 
40   /* Fails if stack pointer corrupted.  */
41   q = __builtin_alloca (x);
42   if (foo (p) < foo (q))
43     {
44       if (foo (q) - foo (p) >= 1024)
45 	abort ();
46     }
47   else if (foo (p) - foo (q) >= 1024)
48     abort ();
49 
50   return 0;
51 }
52