strub: enable conditional support
[official-gcc.git] / gcc / testsuite / c-c++-common / torture / strub-run4.c
blob0e84a4bab80fcf2b0a4abcff22ad9ab9465b99e1
1 /* { dg-do run } */
2 /* { dg-options "-fstrub=all" } */
3 /* { dg-require-effective-target alloca } */
4 /* { dg-require-effective-target strub } */
6 /* Check that multi-level, multi-inlined functions still get cleaned up as
7 expected, without overwriting temporary stack allocations while they should
8 still be available. */
10 #ifndef ATTR_STRUB_AT_CALLS
11 # define ATTR_STRUB_AT_CALLS /* Defined in strub-run4d.c. */
12 #endif
14 const char test_string[] = "\x55\xde\xad\xbe\xef\xc0\x1d\xca\xfe\x55\xaa";
16 static inline __attribute__ ((__always_inline__))
17 char *
18 leak_string (void)
20 int __attribute__ ((__strub__)) len = 512;
21 asm ("" : "+r" (len));
22 char s[len];
23 __builtin_strcpy (s, test_string);
24 __builtin_strcpy (s + len - sizeof (test_string), test_string);
25 asm ("" : "+m" (s));
26 return (char *) __builtin_stack_address ();
29 static inline __attribute__ ((__always_inline__))
30 int
31 look_for_string (char *e)
33 char *p = (char *) __builtin_stack_address ();
35 if (p == e)
36 __builtin_abort ();
38 if (p > e)
40 char *q = p;
41 p = e;
42 e = q;
45 for (char *re = e - sizeof (test_string); p < re; p++)
46 for (int i = 0; p[i] == test_string[i]; i++)
47 if (i == sizeof (test_string) - 1)
48 return i;
50 return 0;
53 static inline ATTR_STRUB_AT_CALLS
54 char *
55 innermost ()
57 int __attribute__ ((__strub__)) len = 512;
58 asm ("" : "+r" (len));
59 char s[len];
60 __builtin_strcpy (s, test_string);
61 __builtin_strcpy (s + len - sizeof (test_string), test_string);
62 asm ("" : "+m" (s));
63 char *ret = leak_string ();
64 if (__builtin_strcmp (s, test_string) != 0)
65 __builtin_abort ();
66 if (__builtin_strcmp (s + len - sizeof (test_string), test_string) != 0)
67 __builtin_abort ();
68 return ret;
71 static inline ATTR_STRUB_AT_CALLS
72 char *
73 intermediate ()
75 int __attribute__ ((__strub__)) len = 512;
76 asm ("" : "+r" (len));
77 char s[len];
78 __builtin_strcpy (s, test_string);
79 __builtin_strcpy (s + len - sizeof (test_string), test_string);
80 asm ("" : "+m" (s));
81 char *ret = innermost ();
82 if (__builtin_strcmp (s, test_string) != 0)
83 __builtin_abort ();
84 if (__builtin_strcmp (s + len - sizeof (test_string), test_string) != 0)
85 __builtin_abort ();
86 return ret;
89 static inline __attribute__ ((__strub__ ("internal")))
90 char *
91 internal ()
93 return intermediate ();
96 int __attribute__ ((__strub__ ("disabled")))
97 main ()
99 /* Since these test check stack contents above the top of the stack, an
100 unexpected asynchronous signal or interrupt might overwrite the bits we
101 expect to find and cause spurious fails. Tolerate one such overall
102 spurious fail by retrying. */
103 int i = 1;
104 while (look_for_string (internal ()))
105 if (!i--) __builtin_abort ();
106 __builtin_exit (0);