xref: /llvm-project/compiler-rt/test/metadata/uar.cpp (revision 6b11573b8c5e3d36beee099dbe7347c2a007bf53)
1 // RUN: %clangxx %s -O1 -o %t -fexperimental-sanitize-metadata=covered,uar && %t | FileCheck %s
2 // RUN: %clangxx %s -O1 -o %t -fexperimental-sanitize-metadata=covered,uar -fsanitize=address,signed-integer-overflow,alignment && %t | FileCheck %s
3 // RUN: %clangxx %s -O1 -o %t -mcmodel=large -fexperimental-sanitize-metadata=covered,uar -fsanitize=address,signed-integer-overflow,alignment && %t | FileCheck %s
4 
5 // CHECK-DAG: metadata add version 2
6 
7 __attribute__((noinline, not_tail_called)) void escape(const volatile void *p) {
8   [[maybe_unused]] static const volatile void *sink;
9   sink = p;
10 }
11 
12 __attribute__((noinline, not_tail_called)) void use(int x) {
13   static volatile int sink;
14   sink += x;
15 }
16 
17 // CHECK-DAG: empty: features=0 stack_args=0
18 void empty() {}
19 
20 // CHECK-DAG: simple: features=0 stack_args=0
21 int simple(int *data, int index) { return data[index + 1]; }
22 
23 // CHECK-DAG: builtins: features=0 stack_args=0
24 int builtins() {
25   int x = 0;
26   __builtin_prefetch(&x);
27   return x;
28 }
29 
30 // CHECK-DAG: ellipsis: features=0 stack_args=0
31 void ellipsis(const char *fmt, ...) {
32   int x;
33   escape(&x);
34 }
35 
36 // CHECK-DAG: non_empty_function: features=2 stack_args=0
37 void non_empty_function() {
38   int x;
39   escape(&x);
40 }
41 
42 // CHECK-DAG: no_stack_args: features=2 stack_args=0
43 void no_stack_args(long a0, long a1, long a2, long a3, long a4, long a5) {
44   int x;
45   escape(&x);
46 }
47 
48 // CHECK-DAG: stack_args: features=6 stack_args=16
49 void stack_args(long a0, long a1, long a2, long a3, long a4, long a5, long a6) {
50   int x;
51   escape(&x);
52 }
53 
54 // CHECK-DAG: more_stack_args: features=6 stack_args=32
55 void more_stack_args(long a0, long a1, long a2, long a3, long a4, long a5,
56                      long a6, long a7, long a8) {
57   int x;
58   escape(&x);
59 }
60 
61 // CHECK-DAG: struct_stack_args: features=6 stack_args=144
62 struct large {
63   char x[131];
64 };
65 void struct_stack_args(large a) {
66   int x;
67   escape(&x);
68 }
69 
70 __attribute__((noinline)) int tail_called(int x) { return x; }
71 
72 // CHECK-DAG: with_tail_call: features=2
73 int with_tail_call(int x) { [[clang::musttail]] return tail_called(x); }
74 
75 __attribute__((noinline, noreturn)) int noreturn(int x) { __builtin_trap(); }
76 
77 // CHECK-DAG: with_noreturn_tail_call: features=0
78 int with_noreturn_tail_call(int x) { return noreturn(x); }
79 
80 // CHECK-DAG: local_array: features=0
81 void local_array(int x) {
82   int data[10];
83   use(data[x]);
84 }
85 
86 // CHECK-DAG: local_alloca: features=0
87 void local_alloca(int size, int i, int j) {
88   volatile int *p = static_cast<int *>(__builtin_alloca(size));
89   p[i] = 0;
90   use(p[j]);
91 }
92 
93 // CHECK-DAG: escaping_alloca: features=2
94 void escaping_alloca(int size, int i) {
95   volatile int *p = static_cast<int *>(__builtin_alloca(size));
96   escape(&p[i]);
97 }
98 
99 #define FUNCTIONS                                                              \
100   FN(empty);                                                                   \
101   FN(simple);                                                                  \
102   FN(builtins);                                                                \
103   FN(ellipsis);                                                                \
104   FN(non_empty_function);                                                      \
105   FN(no_stack_args);                                                           \
106   FN(stack_args);                                                              \
107   FN(more_stack_args);                                                         \
108   FN(struct_stack_args);                                                       \
109   FN(with_tail_call);                                                          \
110   FN(with_noreturn_tail_call);                                                 \
111   FN(local_array);                                                             \
112   FN(local_alloca);                                                            \
113   FN(escaping_alloca);                                                         \
114   /**/
115 
116 #include "common.h"
117