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