1 // REQUIRES: x86-registered-target
2 // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fstrict-flex-arrays=0 -fsanitize=array-bounds %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-0
3 // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fstrict-flex-arrays=0 -fsanitize=array-bounds -x c++ %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-0,CXX,CXX-STRICT-0
4 // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fstrict-flex-arrays=1 -fsanitize=array-bounds %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-1
5 // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fstrict-flex-arrays=1 -fsanitize=array-bounds -x c++ %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-1,CXX
6 // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fstrict-flex-arrays=2 -fsanitize=array-bounds %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-2
7 // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fstrict-flex-arrays=2 -fsanitize=array-bounds -x c++ %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-2,CXX
8 // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fstrict-flex-arrays=3 -fsanitize=array-bounds %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-3
9 // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fstrict-flex-arrays=3 -fsanitize=array-bounds -x c++ %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-3,CXX
10 // Before flexible array member was added to C99, many projects use a
11 // one-element array as the last member of a structure as an alternative.
12 // E.g. https://github.com/python/cpython/issues/84301
13 // Suppress such errors with -fstrict-flex-arrays=0.
36 // CHECK-LABEL: define {{.*}} @{{.*}}test_incomplete{{.*}}(
37 int test_incomplete(struct Incomplete
*p
, int i
) {
38 // CHECK-STRICT-0-NOT: @__ubsan
39 // CHECK-STRICT-1-NOT: @__ubsan
40 // CHECK-STRICT-2-NOT: @__ubsan
41 // CHECK-STRICT-3-NOT: @__ubsan
42 return p
->a
[i
] + (p
->a
)[i
];
45 // CHECK-LABEL: define {{.*}} @{{.*}}test_zero{{.*}}(
46 int test_zero(struct Zero
*p
, int i
) {
47 // CHECK-STRICT-0-NOT: @__ubsan
48 // CHECK-STRICT-1-NOT: @__ubsan
49 // CHECK-STRICT-2-NOT: @__ubsan
50 // CHECK-STRICT-3: call void @__ubsan_handle_out_of_bounds_abort(
51 return p
->a
[i
] + (p
->a
)[i
];
54 // CHECK-LABEL: define {{.*}} @{{.*}}test_one{{.*}}(
55 int test_one(struct One
*p
, int i
) {
56 // CHECK-STRICT-0-NOT: @__ubsan
57 // CHECK-STRICT-1-NOT: @__ubsan
58 // CHECK-STRICT-2: call void @__ubsan_handle_out_of_bounds_abort(
59 // CHECK-STRICT-3: call void @__ubsan_handle_out_of_bounds_abort(
60 return p
->a
[i
] + (p
->a
)[i
];
63 // CHECK-LABEL: define {{.*}} @{{.*}}test_two{{.*}}(
64 int test_two(struct Two
*p
, int i
) {
65 // CHECK-STRICT-0-NOT: @__ubsan
66 // CHECK-STRICT-1: call void @__ubsan_handle_out_of_bounds_abort(
67 // CHECK-STRICT-2: call void @__ubsan_handle_out_of_bounds_abort(
68 return p
->a
[i
] + (p
->a
)[i
];
71 // CHECK-LABEL: define {{.*}} @{{.*}}test_three{{.*}}(
72 int test_three(struct Three
*p
, int i
) {
73 // CHECK-STRICT-0-NOT: @__ubsan
74 // CHECK-STRICT-1: call void @__ubsan_handle_out_of_bounds_abort(
75 // CHECK-STRICT-2: call void @__ubsan_handle_out_of_bounds_abort(
76 // CHECK-STRICT-3: call void @__ubsan_handle_out_of_bounds_abort(
77 return p
->a
[i
] + (p
->a
)[i
];
93 // CHECK-LABEL: define {{.*}} @{{.*}}test_uzero{{.*}}(
94 int test_uzero(union uZero
*p
, int i
) {
95 // CHECK-STRICT-0-NOT: @__ubsan
96 // CHECK-STRICT-1-NOT: @__ubsan
97 // CHECK-STRICT-2-NOT: @__ubsan
98 // CHECK-STRICT-3: call void @__ubsan_handle_out_of_bounds_abort(
99 return p
->a
[i
] + (p
->a
)[i
];
102 // CHECK-LABEL: define {{.*}} @{{.*}}test_uone{{.*}}(
103 int test_uone(union uOne
*p
, int i
) {
104 // CHECK-STRICT-0-NOT: @__ubsan
105 // CHECK-STRICT-1-NOT: @__ubsan
106 // CHECK-STRICT-2: call void @__ubsan_handle_out_of_bounds_abort(
107 // CHECK-STRICT-3: call void @__ubsan_handle_out_of_bounds_abort(
108 return p
->a
[i
] + (p
->a
)[i
];
111 // CHECK-LABEL: define {{.*}} @{{.*}}test_utwo{{.*}}(
112 int test_utwo(union uTwo
*p
, int i
) {
113 // CHECK-STRICT-0-NOT: @__ubsan
114 // CHECK-STRICT-1: call void @__ubsan_handle_out_of_bounds_abort(
115 // CHECK-STRICT-2: call void @__ubsan_handle_out_of_bounds_abort(
116 // CHECK-STRICT-3: call void @__ubsan_handle_out_of_bounds_abort(
117 return p
->a
[i
] + (p
->a
)[i
];
120 // CHECK-LABEL: define {{.*}} @{{.*}}test_uthree{{.*}}(
121 int test_uthree(union uThree
*p
, int i
) {
122 // CHECK-STRICT-0-NOT: @__ubsan
123 // CHECK-STRICT-1: call void @__ubsan_handle_out_of_bounds_abort(
124 // CHECK-STRICT-2: call void @__ubsan_handle_out_of_bounds_abort(
125 // CHECK-STRICT-3: call void @__ubsan_handle_out_of_bounds_abort(
126 return p
->a
[i
] + (p
->a
)[i
];
134 // CHECK-LABEL: define {{.*}} @{{.*}}test_macro{{.*}}(
135 int test_macro(struct Macro
*p
, int i
) {
136 // CHECK-STRICT-0-NOT: @__ubsan
137 // CHECK-STRICT-1-NOT: @__ubsan
138 // CHECK-STRICT-2: call void @__ubsan_handle_out_of_bounds_abort(
139 // CHECK-STRICT-3: call void @__ubsan_handle_out_of_bounds_abort(
140 return p
->a
[i
] + (p
->a
)[i
];
143 #if defined __cplusplus
148 struct NoStandardLayout
: Base
{
152 // CXX-LABEL: define {{.*}} @{{.*}}test_nostandardlayout{{.*}}(
153 int test_nostandardlayout(NoStandardLayout
*p
, int i
) {
154 // CXX-STRICT-0-NOT: @__ubsan
155 return p
->a
[i
] + (p
->a
)[i
];
158 template<int N
> struct Template
{
162 // CXX-LABEL: define {{.*}} @{{.*}}test_template{{.*}}(
163 int test_template(Template
<1> *p
, int i
) {
164 // CXX-STRICT-0-NOT: @__ubsan
165 return p
->a
[i
] + (p
->a
)[i
];