111
|
1 /* { dg-do run } */
|
|
2 /* { dg-set-target-env-var ASAN_OPTIONS "detect_stack_use_after_return=1" } */
|
|
3 /* { dg-shouldfail "asan" } */
|
|
4
|
|
5 #include <stdio.h>
|
|
6 #include <pthread.h>
|
|
7
|
|
8 #ifndef kSize
|
|
9 # define kSize 1
|
|
10 #endif
|
|
11
|
|
12 #ifndef UseThread
|
|
13 # define UseThread 0
|
|
14 #endif
|
|
15
|
|
16 __attribute__((noinline))
|
|
17 char *Ident(char *x) {
|
|
18 fprintf(stderr, "1: %p\n", x);
|
|
19 return x;
|
|
20 }
|
|
21
|
|
22 __attribute__((noinline))
|
|
23 char *Func1() {
|
|
24 char local[kSize];
|
|
25 return Ident(local);
|
|
26 }
|
|
27
|
|
28 __attribute__((noinline))
|
|
29 void Func2(char *x) {
|
|
30 fprintf(stderr, "2: %p\n", x);
|
|
31 *x = 1;
|
|
32 }
|
|
33
|
|
34 void *Thread(void *unused) {
|
|
35 Func2(Func1());
|
|
36 return NULL;
|
|
37 }
|
|
38
|
|
39 int main(int argc, char **argv) {
|
|
40 #if UseThread
|
|
41 pthread_t t;
|
|
42 pthread_create(&t, 0, Thread, 0);
|
|
43 pthread_join(t, 0);
|
|
44 #else
|
|
45 Func2(Func1());
|
|
46 #endif
|
|
47 return 0;
|
|
48 }
|
|
49
|
|
50 /* { dg-output "WRITE of size 1 at .* thread T0.*" } */
|
|
51 /* { dg-output " #0.*(Func2)?.*use-after-return-1.(c:31)?.*" } */
|
|
52 /* { dg-output "is located in stack of thread T0 at offset.*" } */
|
|
53 /* { dg-output "\'local\' <== Memory access at offset 32 is inside this variable" } */
|