1 // Tests use-after-scope detection and reporting.
2 // RUN: %clang_hwasan -mllvm -hwasan-use-after-scope -g %s -o %t && not %run %t 2>&1 | FileCheck %s
3 // RUN: %clang_hwasan -mllvm -hwasan-use-after-scope -g %s -o %t && not %env_hwasan_opts=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM
4
5 // RUN: %clang_hwasan -mllvm -hwasan-use-after-scope=false -g %s -o %t && %run %t 2>&1
6 // Use after scope is turned off by default.
7 // RUN: %clang_hwasan -g %s -o %t && %run %t 2>&1
8
9 // RUN: %clang_hwasan -mllvm -hwasan-use-after-scope -g %s -o %t && not %run %t 2>&1 | FileCheck %s
10
11 // Run the same test as above, but using the __hwasan_add_frame_record libcall.
12 // The output should be the exact same.
13 // RUN: %clang_hwasan -mllvm -hwasan-use-after-scope -mllvm -hwasan-record-stack-history=libcall -g %s -o %t && not %env_hwasan_opts=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM
14
15 // REQUIRES: stable-runtime
16
17 // Stack histories currently are not recorded on x86.
18 // XFAIL: x86_64
19
USE(void * x)20 void USE(void *x) { // pretend_to_do_something(void *x)
21 __asm__ __volatile__(""
22 :
23 : "r"(x)
24 : "memory");
25 }
26
Unrelated1()27 __attribute__((noinline)) void Unrelated1() {
28 int A[2];
29 USE(&A[0]);
30 }
Unrelated2()31 __attribute__((noinline)) void Unrelated2() {
32 int BB[3];
33 USE(&BB[0]);
34 }
Unrelated3()35 __attribute__((noinline)) void Unrelated3() {
36 int CCC[4];
37 USE(&CCC[0]);
38 }
39
buggy()40 __attribute__((noinline)) char buggy() {
41 char *volatile p;
42 {
43 char zzz[0x1000];
44 p = zzz;
45 }
46 return *p;
47 }
48
main()49 int main() {
50 Unrelated1();
51 Unrelated2();
52 Unrelated3();
53 char p = buggy();
54 return p;
55 // CHECK: READ of size 1 at
56 // CHECK: #0 {{.*}} in buggy{{.*}}stack-uas.c:[[@LINE-10]]
57 // CHECK: Cause: stack tag-mismatch
58 // CHECK: is located in stack of thread
59 // CHECK: Potentially referenced stack objects:
60 // CHECK-NEXT: zzz in buggy {{.*}}stack-uas.c:[[@LINE-17]]
61 // CHECK-NEXT: Memory tags around the buggy address
62
63 // NOSYM: Previously allocated frames:
64 // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uas.c.tmp+0x{{.*}}){{$}}
65 // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uas.c.tmp+0x{{.*}}){{$}}
66 // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uas.c.tmp+0x{{.*}}){{$}}
67 // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uas.c.tmp+0x{{.*}}){{$}}
68 // NOSYM-NEXT: Memory tags around the buggy address
69
70 // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in buggy
71 }
72