1 // RUN: %clang_cc1 -triple x86_64-gnu-linux -fsanitize=array-bounds,enum,float-cast-overflow,integer-divide-by-zero,implicit-unsigned-integer-truncation,implicit-signed-integer-truncation,implicit-integer-sign-change,unsigned-integer-overflow,signed-integer-overflow,shift-base,shift-exponent -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s
4 // CHECK: define{{.*}} void @_Z6BoundsRA10_KiDB15_
5 void Bounds(const int (&Array
)[10], _BitInt(15) Index
) {
7 // CHECK: %[[SEXT:.+]] = sext i15 %{{.+}} to i64
8 // CHECK: %[[CMP:.+]] = icmp ult i64 %[[SEXT]], 10
9 // CHECK: br i1 %[[CMP]]
10 // CHECK: call void @__ubsan_handle_out_of_bounds
13 // CHECK: define{{.*}} void @_Z4Enumv
15 enum E1
{ e1a
= 0, e1b
= 127 }
17 enum E2
{ e2a
= -1, e2b
= 64 }
19 enum E3
{ e3a
= (1u << 31) - 1 }
23 // CHECK: %[[E1:.+]] = icmp ule i32 %{{.*}}, 127
24 // CHECK: br i1 %[[E1]]
25 // CHECK: call void @__ubsan_handle_load_invalid_value_abort
27 // CHECK: %[[E2HI:.*]] = icmp sle i32 {{.*}}, 127
28 // CHECK: %[[E2LO:.*]] = icmp sge i32 {{.*}}, -128
29 // CHECK: %[[E2:.*]] = and i1 %[[E2HI]], %[[E2LO]]
30 // CHECK: br i1 %[[E2]]
31 // CHECK: call void @__ubsan_handle_load_invalid_value_abort
33 // CHECK: %[[E3:.*]] = icmp ule i32 {{.*}}, 2147483647
34 // CHECK: br i1 %[[E3]]
35 // CHECK: call void @__ubsan_handle_load_invalid_value_abort
38 // CHECK: define{{.*}} void @_Z13FloatOverflowfd
39 void FloatOverflow(float f
, double d
) {
41 // CHECK: fcmp ogt float %{{.+}}, -5.130000e+02
42 // CHECK: fcmp olt float %{{.+}}, 5.120000e+02
44 // CHECK: fcmp ogt double %{{.+}}, -5.130000e+02
45 // CHECK: fcmp olt double %{{.+}}, 5.120000e+02
47 // CHECK: fcmp ogt float %{{.+}}, -6.500000e+01
48 // CHECK: fcmp olt float %{{.+}}, 6.400000e+01
50 // CHECK: fcmp ogt double %{{.+}}, -6.500000e+01
51 // CHECK: fcmp olt double %{{.+}}, 6.400000e+01
54 // CHECK: define{{.*}} void @_Z14UIntTruncationDU35_jy
55 void UIntTruncation(unsigned _BitInt(35) E
, unsigned int i
, unsigned long long ll
) {
58 // CHECK: %[[LOADE:.+]] = load i64
59 // CHECK: %[[E1:.+]] = trunc i64 %[[LOADE]] to i35
60 // CHECK: %[[STOREDV:.+]] = zext i35 %[[E1]] to i64
61 // CHECK: store i64 %[[STOREDV]], ptr %[[EADDR:.+]]
62 // CHECK: %[[LOADE2:.+]] = load i64, ptr %[[EADDR]]
63 // CHECK: %[[LOADEDV:.+]] = trunc i64 %[[LOADE2]] to i35
64 // CHECK: %[[CONV:.+]] = trunc i35 %[[LOADEDV]] to i32
65 // CHECK: %[[EXT:.+]] = zext i32 %[[CONV]] to i35
66 // CHECK: %[[CHECK:.+]] = icmp eq i35 %[[EXT]], %[[LOADEDV]]
67 // CHECK: br i1 %[[CHECK]]
68 // CHECK: call void @__ubsan_handle_implicit_conversion_abort
71 // CHECK: %[[LOADLL:.+]] = load i64
72 // CHECK: %[[CONV:.+]] = trunc i64 %[[LOADLL]] to i35
73 // CHECK: %[[EXT:.+]] = zext i35 %[[CONV]] to i64
74 // CHECK: %[[CHECK:.+]] = icmp eq i64 %[[EXT]], %[[LOADLL]]
75 // CHECK: br i1 %[[CHECK]]
76 // CHECK: call void @__ubsan_handle_implicit_conversion_abort
79 // CHECK: define{{.*}} void @_Z13IntTruncationDB35_DU42_ij
80 void IntTruncation(_BitInt(35) E
, unsigned _BitInt(42) UE
, int i
, unsigned j
) {
83 // CHECK: %[[LOADE:.+]] = load i64
84 // CHECK: %[[E1:.+]] = trunc i64 %[[LOADE]] to i35
85 // CHECK: %[[STOREDV:.+]] = sext i35 %[[E1]] to i64
86 // CHECK: store i64 %[[STOREDV]], ptr %[[EADDR:.+]]
87 // CHECK: %[[LOADE2:.+]] = load i64, ptr %[[EADDR]]
88 // CHECK: %[[LOADEDV:.+]] = trunc i64 %[[LOADE2]] to i35
89 // CHECK: %[[CONV:.+]] = trunc i35 %[[LOADEDV]] to i32
90 // CHECK: %[[EXT:.+]] = zext i32 %[[CONV]] to i35
91 // CHECK: %[[CHECK:.+]] = icmp eq i35 %[[EXT]], %[[LOADEDV]]
92 // CHECK: br i1 %[[CHECK]]
93 // CHECK: call void @__ubsan_handle_implicit_conversion_abort
96 // CHECK: %[[LOADUE:.+]] = load i64
97 // CHECK: %[[LOADEDV:.+]] = trunc i64 %[[LOADUE]] to i42
98 // CHECK: %[[CONV:.+]] = trunc i42 %[[LOADEDV]] to i32
99 // CHECK: %[[EXT:.+]] = zext i32 %[[CONV]] to i42
100 // CHECK: %[[CHECK:.+]] = icmp eq i42 %[[EXT]], %[[LOADEDV]]
101 // CHECK: br i1 %[[CHECK]]
102 // CHECK: call void @__ubsan_handle_implicit_conversion_abort
104 // Note: also triggers sign change check.
106 // CHECK: %[[LOADUE:.+]] = load i64
107 // CHECK: %[[LOADEDV:.+]] = trunc i64 %[[LOADUE]] to i42
108 // CHECK: %[[CONV:.+]] = trunc i42 %[[LOADEDV]] to i32
109 // CHECK: %[[NEG:.+]] = icmp slt i32 %[[CONV]], 0
110 // CHECK: %[[SIGNCHECK:.+]] = icmp eq i1 false, %[[NEG]]
111 // CHECK: %[[EXT:.+]] = sext i32 %[[CONV]] to i42
112 // CHECK: %[[CHECK:.+]] = icmp eq i42 %[[EXT]], %[[LOADEDV]]
113 // CHECK: %[[CHECKBOTH:.+]] = and i1 %[[SIGNCHECK]], %[[CHECK]]
114 // CHECK: br i1 %[[CHECKBOTH]]
115 // CHECK: call void @__ubsan_handle_implicit_conversion_abort
117 // Note: also triggers sign change check.
119 // CHECK: %[[LOADUE:.+]] = load i64
120 // CHECK: %[[LOADEDV:.+]] = trunc i64 %[[LOADUE]] to i42
121 // CHECK: %[[CONV:.+]] = trunc i42 %[[LOADEDV]] to i35
122 // CHECK: %[[NEG:.+]] = icmp slt i35 %[[CONV]], 0
123 // CHECK: %[[SIGNCHECK:.+]] = icmp eq i1 false, %[[NEG]]
124 // CHECK: %[[EXT:.+]] = sext i35 %[[CONV]] to i42
125 // CHECK: %[[CHECK:.+]] = icmp eq i42 %[[EXT]], %[[LOADEDV]]
126 // CHECK: %[[CHECKBOTH:.+]] = and i1 %[[SIGNCHECK]], %[[CHECK]]
127 // CHECK: br i1 %[[CHECKBOTH]]
128 // CHECK: call void @__ubsan_handle_implicit_conversion_abort
131 // CHECK: define{{.*}} void @_Z15SignChangeCheckDU39_DB39_
132 void SignChangeCheck(unsigned _BitInt(39) UE
, _BitInt(39) E
) {
134 // CHECK: %[[LOADEU:.+]] = load i64
135 // CHECK: %[[LOADE:.+]] = load i64
136 // CHECK: %[[LOADEDV:.+]] = trunc i64 %[[LOADE]] to i39
137 // CHECK: %[[STOREDV:.+]] = sext i39 %[[LOADEDV]] to i64
138 // CHECK: store i64 %[[STOREDV]], ptr %[[EADDR:.+]]
139 // CHECK: %[[LOADE2:.+]] = load i64, ptr %[[EADDR]]
140 // CHECK: %[[LOADEDV2:.+]] = trunc i64 %[[LOADE2]] to i39
141 // CHECK: %[[NEG:.+]] = icmp slt i39 %[[LOADEDV2]], 0
142 // CHECK: %[[SIGNCHECK:.+]] = icmp eq i1 %[[NEG]], false
143 // CHECK: br i1 %[[SIGNCHECK]]
144 // CHECK: call void @__ubsan_handle_implicit_conversion_abort
147 // CHECK: %[[STOREDV2:.+]] = zext i39 %[[LOADEDV2]] to i64
148 // CHECK: store i64 %[[STOREDV2]], ptr %[[UEADDR:.+]]
149 // CHECK: %[[LOADUE2:.+]] = load i64, ptr %[[UEADDR]]
150 // CHECK: %[[LOADEDV3:.+]] = trunc i64 %[[LOADUE2]] to i39
151 // CHECK: %[[NEG:.+]] = icmp slt i39 %[[LOADEDV3]], 0
152 // CHECK: %[[SIGNCHECK:.+]] = icmp eq i1 false, %[[NEG]]
153 // CHECK: br i1 %[[SIGNCHECK]]
154 // CHECK: call void @__ubsan_handle_implicit_conversion_abort
157 // CHECK: define{{.*}} void @_Z9DivByZeroDB11_i
158 void DivByZero(_BitInt(11) E
, int i
) {
160 // Also triggers signed integer overflow.
162 // CHECK: %[[EADDR:.+]] = alloca i16
163 // CHECK: %[[E:.+]] = load i16, ptr %[[EADDR]]
164 // CHECK: %[[LOADEDE:.+]] = trunc i16 %[[E]] to i11
165 // CHECK: %[[E2:.+]] = load i16, ptr %[[EADDR]]
166 // CHECK: %[[LOADEDE2:.+]] = trunc i16 %[[E2]] to i11
167 // CHECK: %[[NEZERO:.+]] = icmp ne i11 %[[LOADEDE2]], 0
168 // CHECK: %[[NEMIN:.+]] = icmp ne i11 %[[LOADEDE]], -1024
169 // CHECK: %[[NENEG1:.+]] = icmp ne i11 %[[LOADEDE2]], -1
170 // CHECK: %[[OR:.+]] = or i1 %[[NEMIN]], %[[NENEG1]]
171 // CHECK: %[[AND:.+]] = and i1 %[[NEZERO]], %[[OR]]
172 // CHECK: br i1 %[[AND]]
173 // CHECK: call void @__ubsan_handle_divrem_overflow_abort
177 //-fsanitize=shift: (shift-base, shift-exponent) Shift operators where the amount shifted is greater or equal to the promoted bit-width of the left hand side or less than zero, or where the left hand side is negative. For a signed left shift, also checks for signed overflow in C, and for unsigned overflow in C++. You can use -fsanitize=shift-base or -fsanitize=shift-exponent to check only left-hand side or right-hand side of shift operation, respectively.
178 // CHECK: define{{.*}} void @_Z6ShiftsDB9_
179 void Shifts(_BitInt(9) E
) {
181 // CHECK: %[[EADDR:.+]] = alloca i16
182 // CHECK: %[[LHSE:.+]] = load i16, ptr %[[EADDR]]
183 // CHECK: %[[RHSE:.+]] = load i16, ptr %[[EADDR]]
184 // CHECK: %[[LOADED:.+]] = trunc i16 %[[RHSE]] to i9
185 // CHECK: %[[CMP:.+]] = icmp ule i9 %[[LOADED]], 8
186 // CHECK: br i1 %[[CMP]]
187 // CHECK: call void @__ubsan_handle_shift_out_of_bounds_abort
190 // CHECK: %[[LHSE:.+]] = load i16, ptr
191 // CHECK: %[[LOADEDL:.+]] = trunc i16 %[[LHSE]] to i9
192 // CHECK: %[[RHSE:.+]] = load i16, ptr
193 // CHECK: %[[LOADED:.+]] = trunc i16 %[[RHSE]] to i9
194 // CHECK: %[[CMP:.+]] = icmp ule i9 %[[LOADED]], 8
195 // CHECK: br i1 %[[CMP]]
196 // CHECK: %[[ZEROS:.+]] = sub nuw nsw i9 8, %[[LOADED]]
197 // CHECK: %[[CHECK:.+]] = lshr i9 %[[LOADEDL]], %[[ZEROS]]
198 // CHECK: %[[SKIPSIGN:.+]] = lshr i9 %[[CHECK]], 1
199 // CHECK: %[[CHECK:.+]] = icmp eq i9 %[[SKIPSIGN]]
200 // CHECK: %[[PHI:.+]] = phi i1 [ true, %{{.+}} ], [ %[[CHECK]], %{{.+}} ]
201 // CHECK: and i1 %[[CMP]], %[[PHI]]
202 // CHECK: call void @__ubsan_handle_shift_out_of_bounds_abort
205 // CHECK: define{{.*}} void @_Z21SignedIntegerOverflowDB93_DB4_DB31_
206 void SignedIntegerOverflow(_BitInt(93) BiggestE
,
207 _BitInt(4) SmallestE
,
208 _BitInt(31) JustRightE
) {
210 // CHECK: %[[LOADBIGGESTE2:.+]] = load i128
211 // CHECK: %[[LOADEDV:.+]] = trunc i128 %[[LOADBIGGESTE2]] to i93
212 // CHECK: %[[STOREDV:.+]] = sext i93 %[[LOADEDV]] to i128
213 // CHECK: store i128 %[[STOREDV]], ptr %[[BIGGESTEADDR:.+]]
214 // CHECK: %[[LOAD1:.+]] = load i128, ptr %[[BIGGESTEADDR]]
215 // CHECK: %[[LOADEDV1:.+]] = trunc i128 %[[LOAD1]] to i93
216 // CHECK: %[[LOAD2:.+]] = load i128, ptr %[[BIGGESTEADDR]]
217 // CHECK: %[[LOADEDV2:.+]] = trunc i128 %[[LOAD2]] to i93
218 // CHECK: %[[OFCALL:.+]] = call { i93, i1 } @llvm.sadd.with.overflow.i93(i93 %[[LOADEDV1]], i93 %[[LOADEDV2]])
219 // CHECK: %[[EXRESULT:.+]] = extractvalue { i93, i1 } %[[OFCALL]], 0
220 // CHECK: %[[OFRESULT:.+]] = extractvalue { i93, i1 } %[[OFCALL]], 1
221 // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true
222 // CHECK: br i1 %[[CHECK]]
223 // CHECK: call void @__ubsan_handle_add_overflow_abort
225 SmallestE
- SmallestE
;
226 // CHECK: %[[LOAD1:.+]] = load i8, ptr
227 // CHECK: %[[LOADEDV1:.+]] = trunc i8 %[[LOAD1]] to i4
228 // CHECK: %[[LOAD2:.+]] = load i8, ptr
229 // CHECK: %[[LOADEDV2:.+]] = trunc i8 %[[LOAD2]] to i4
230 // CHECK: %[[OFCALL:.+]] = call { i4, i1 } @llvm.ssub.with.overflow.i4(i4 %[[LOADEDV1]], i4 %[[LOADEDV2]])
231 // CHECK: %[[EXRESULT:.+]] = extractvalue { i4, i1 } %[[OFCALL]], 0
232 // CHECK: %[[OFRESULT:.+]] = extractvalue { i4, i1 } %[[OFCALL]], 1
233 // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true
234 // CHECK: br i1 %[[CHECK]]
235 // CHECK: call void @__ubsan_handle_sub_overflow_abort
237 JustRightE
* JustRightE
;
238 // CHECK: %[[LOAD1:.+]] = load i32, ptr
239 // CHECK: %[[LOADEDV1:.+]] = trunc i32 %[[LOAD1]] to i31
240 // CHECK: %[[LOAD2:.+]] = load i32, ptr
241 // CHECK: %[[LOADEDV2:.+]] = trunc i32 %[[LOAD2]] to i31
242 // CHECK: %[[OFCALL:.+]] = call { i31, i1 } @llvm.smul.with.overflow.i31(i31 %[[LOADEDV1]], i31 %[[LOADEDV2]])
243 // CHECK: %[[EXRESULT:.+]] = extractvalue { i31, i1 } %[[OFCALL]], 0
244 // CHECK: %[[OFRESULT:.+]] = extractvalue { i31, i1 } %[[OFCALL]], 1
245 // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true
246 // CHECK: br i1 %[[CHECK]]
247 // CHECK: call void @__ubsan_handle_mul_overflow_abort
250 // CHECK: define{{.*}} void @_Z23UnsignedIntegerOverflowjDU23_DU35_
251 void UnsignedIntegerOverflow(unsigned u
,
252 unsigned _BitInt(23) SmallE
,
253 unsigned _BitInt(35) BigE
) {
255 // CHECK: %[[LOADE1:.+]] = load i32, ptr
256 // CHECK-NEXT: %[[LOADEDV1:.+]] = trunc i32 %[[LOADE1]] to i23
257 // CHECK: %[[LOADE2:.+]] = load i32, ptr
258 // CHECK-NEXT: %[[LOADEDV2:.+]] = trunc i32 %[[LOADE2]] to i23
259 // CHECK: %[[OFCALL:.+]] = call { i23, i1 } @llvm.uadd.with.overflow.i23(i23 %[[LOADEDV1]], i23 %[[LOADEDV2]])
260 // CHECK: %[[EXRESULT:.+]] = extractvalue { i23, i1 } %[[OFCALL]], 0
261 // CHECK: %[[OFRESULT:.+]] = extractvalue { i23, i1 } %[[OFCALL]], 1
262 // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true
263 // CHECK: br i1 %[[CHECK]]
264 // CHECK: call void @__ubsan_handle_add_overflow_abort
267 // CHECK: %[[LOADU1:.+]] = load i32, ptr
268 // CHECK: %[[LOADU2:.+]] = load i32, ptr
269 // CHECK: %[[OFCALL:.+]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %[[LOADU1]], i32 %[[LOADU2]])
270 // CHECK: %[[EXRESULT:.+]] = extractvalue { i32, i1 } %[[OFCALL]], 0
271 // CHECK: %[[OFRESULT:.+]] = extractvalue { i32, i1 } %[[OFCALL]], 1
272 // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true
273 // CHECK: br i1 %[[CHECK]]
274 // CHECK: call void @__ubsan_handle_add_overflow_abort
276 SmallE
= SmallE
+ SmallE
;
277 // CHECK: %[[LOADE1:.+]] = load i32, ptr
278 // CHECK-NEXT: %[[LOADEDV1:.+]] = trunc i32 %[[LOADE1]] to i23
279 // CHECK: %[[LOADE2:.+]] = load i32, ptr
280 // CHECK-NEXT: %[[LOADEDV2:.+]] = trunc i32 %[[LOADE2]] to i23
281 // CHECK: %[[OFCALL:.+]] = call { i23, i1 } @llvm.uadd.with.overflow.i23(i23 %[[LOADEDV1]], i23 %[[LOADEDV2]])
282 // CHECK: %[[EXRESULT:.+]] = extractvalue { i23, i1 } %[[OFCALL]], 0
283 // CHECK: %[[OFRESULT:.+]] = extractvalue { i23, i1 } %[[OFCALL]], 1
284 // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true
285 // CHECK: br i1 %[[CHECK]]
286 // CHECK: call void @__ubsan_handle_add_overflow_abort
288 SmallE
= BigE
+ BigE
;
289 // CHECK: %[[LOADE1:.+]] = load i64, ptr
290 // CHECK-NEXT: %[[LOADEDV1:.+]] = trunc i64 %[[LOADE1]] to i35
291 // CHECK: %[[LOADE2:.+]] = load i64, ptr
292 // CHECK-NEXT: %[[LOADEDV2:.+]] = trunc i64 %[[LOADE2]] to i35
293 // CHECK: %[[OFCALL:.+]] = call { i35, i1 } @llvm.uadd.with.overflow.i35(i35 %[[LOADEDV1]], i35 %[[LOADEDV2]])
294 // CHECK: %[[EXRESULT:.+]] = extractvalue { i35, i1 } %[[OFCALL]], 0
295 // CHECK: %[[OFRESULT:.+]] = extractvalue { i35, i1 } %[[OFCALL]], 1
296 // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true
297 // CHECK: br i1 %[[CHECK]]
298 // CHECK: call void @__ubsan_handle_add_overflow_abort
301 // CHECK: %[[LOADE1:.+]] = load i64, ptr
302 // CHECK-NEXT: %[[LOADEDV1:.+]] = trunc i64 %[[LOADE1]] to i35
303 // CHECK: %[[LOADE2:.+]] = load i64, ptr
304 // CHECK-NEXT: %[[LOADEDV2:.+]] = trunc i64 %[[LOADE2]] to i35
305 // CHECK: %[[OFCALL:.+]] = call { i35, i1 } @llvm.uadd.with.overflow.i35(i35 %[[LOADEDV1]], i35 %[[LOADEDV2]])
306 // CHECK: %[[EXRESULT:.+]] = extractvalue { i35, i1 } %[[OFCALL]], 0
307 // CHECK: %[[OFRESULT:.+]] = extractvalue { i35, i1 } %[[OFCALL]], 1
308 // CHECK: %[[CHECK:.+]] = xor i1 %[[OFRESULT]], true
309 // CHECK: br i1 %[[CHECK]]
310 // CHECK: call void @__ubsan_handle_add_overflow_abort