1 // RUN: %clangxx_hwasan %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=GOOD
2 // RUN: %clangxx_hwasan -DNO_SANITIZE_F %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=GOOD
3 // RUN: %clangxx_hwasan_oldrt %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=GOOD
4 // RUN: %clangxx_hwasan_oldrt %s -mllvm -hwasan-instrument-landing-pads=0 -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=BAD
5 
6 // C++ tests on x86_64 require instrumented libc++/libstdc++.
7 // REQUIRES: aarch64-target-arch
8 
9 #include <stdexcept>
10 #include <cstdio>
11 
12 static void optimization_barrier(void* arg) {
13   asm volatile("" : : "r"(arg) : "memory");
14 }
15 
16 __attribute__((noinline))
17 void h() {
18   char x[1000];
19   optimization_barrier(x);
20   throw std::runtime_error("hello");
21 }
22 
23 __attribute__((noinline))
24 void g() {
25   char x[1000];
26   optimization_barrier(x);
27   h();
28   optimization_barrier(x);
29 }
30 
31 __attribute__((noinline))
32 void hwasan_read(char *p, int size) {
33   char volatile sink;
34   for (int i = 0; i < size; ++i)
35     sink = p[i];
36 }
37 
38 __attribute__((noinline, no_sanitize("hwaddress"))) void after_catch() {
39   char x[10000];
40   hwasan_read(&x[0], sizeof(x));
41 }
42 
43 
44 __attribute__((noinline))
45 #ifdef NO_SANITIZE_F
46 __attribute__((no_sanitize("hwaddress")))
47 #endif
48 void f() {
49   char x[1000];
50   try {
51     // Put two tagged frames on the stack, throw an exception from the deepest one.
52     g();
53   } catch (const std::runtime_error &e) {
54     // Put an untagged frame on stack, check that it is indeed untagged.
55     // This relies on exception support zeroing out stack tags.
56     // BAD: tag-mismatch
57     after_catch();
58     // Check that an in-scope stack allocation is still tagged.
59     // This relies on exception support not zeroing too much.
60     hwasan_read(&x[0], sizeof(x));
61     // GOOD: hello
62     printf("%s\n", e.what());
63   }
64 }
65 
66 int main() {
67   f();
68 }
69