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