1 // Test CodeGen for Security Check Overflow Builtins.
2 // rdar://13421498
3
4 // RUN: %clang_cc1 -triple "i686-unknown-unknown" -emit-llvm -x c %s -o - | FileCheck %s
5 // RUN: %clang_cc1 -triple "x86_64-unknown-unknown" -emit-llvm -x c %s -o - | FileCheck %s
6 // RUN: %clang_cc1 -triple "x86_64-mingw32" -emit-llvm -x c %s -o - | FileCheck %s
7
8 extern unsigned UnsignedErrorCode;
9 extern unsigned long UnsignedLongErrorCode;
10 extern unsigned long long UnsignedLongLongErrorCode;
11 extern int IntErrorCode;
12 extern long LongErrorCode;
13 extern long long LongLongErrorCode;
14 void overflowed(void);
15
test_add_overflow_uint_uint_uint(unsigned x,unsigned y)16 unsigned test_add_overflow_uint_uint_uint(unsigned x, unsigned y) {
17 // CHECK-LABEL: define i32 @test_add_overflow_uint_uint_uint
18 // CHECK-NOT: ext
19 // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
20 // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
21 // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
22 // CHECK: store i32 [[Q]], i32*
23 // CHECK: br i1 [[C]]
24 unsigned r;
25 if (__builtin_add_overflow(x, y, &r))
26 overflowed();
27 return r;
28 }
29
test_add_overflow_int_int_int(int x,int y)30 int test_add_overflow_int_int_int(int x, int y) {
31 // CHECK-LABEL: define i32 @test_add_overflow_int_int_int
32 // CHECK-NOT: ext
33 // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
34 // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
35 // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
36 // CHECK: store i32 [[Q]], i32*
37 // CHECK: br i1 [[C]]
38 int r;
39 if (__builtin_add_overflow(x, y, &r))
40 overflowed();
41 return r;
42 }
43
test_sub_overflow_uint_uint_uint(unsigned x,unsigned y)44 unsigned test_sub_overflow_uint_uint_uint(unsigned x, unsigned y) {
45 // CHECK-LABEL: define i32 @test_sub_overflow_uint_uint_uint
46 // CHECK-NOT: ext
47 // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
48 // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
49 // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
50 // CHECK: store i32 [[Q]], i32*
51 // CHECK: br i1 [[C]]
52 unsigned r;
53 if (__builtin_sub_overflow(x, y, &r))
54 overflowed();
55 return r;
56 }
57
test_sub_overflow_int_int_int(int x,int y)58 int test_sub_overflow_int_int_int(int x, int y) {
59 // CHECK-LABEL: define i32 @test_sub_overflow_int_int_int
60 // CHECK-NOT: ext
61 // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
62 // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
63 // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
64 // CHECK: store i32 [[Q]], i32*
65 // CHECK: br i1 [[C]]
66 int r;
67 if (__builtin_sub_overflow(x, y, &r))
68 overflowed();
69 return r;
70 }
71
test_mul_overflow_uint_uint_uint(unsigned x,unsigned y)72 unsigned test_mul_overflow_uint_uint_uint(unsigned x, unsigned y) {
73 // CHECK-LABEL: define i32 @test_mul_overflow_uint_uint_uint
74 // CHECK-NOT: ext
75 // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
76 // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
77 // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
78 // CHECK: store i32 [[Q]], i32*
79 // CHECK: br i1 [[C]]
80 unsigned r;
81 if (__builtin_mul_overflow(x, y, &r))
82 overflowed();
83 return r;
84 }
85
test_mul_overflow_int_int_int(int x,int y)86 int test_mul_overflow_int_int_int(int x, int y) {
87 // CHECK-LABEL: define i32 @test_mul_overflow_int_int_int
88 // CHECK-NOT: ext
89 // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
90 // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
91 // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
92 // CHECK: store i32 [[Q]], i32*
93 // CHECK: br i1 [[C]]
94 int r;
95 if (__builtin_mul_overflow(x, y, &r))
96 overflowed();
97 return r;
98 }
99
test_add_overflow_uint_int_int(unsigned x,int y)100 int test_add_overflow_uint_int_int(unsigned x, int y) {
101 // CHECK-LABEL: define i32 @test_add_overflow_uint_int_int
102 // CHECK: [[XE:%.+]] = zext i32 %{{.+}} to i33
103 // CHECK: [[YE:%.+]] = sext i32 %{{.+}} to i33
104 // CHECK: [[S:%.+]] = call { i33, i1 } @llvm.sadd.with.overflow.i33(i33 [[XE]], i33 [[YE]])
105 // CHECK-DAG: [[Q:%.+]] = extractvalue { i33, i1 } [[S]], 0
106 // CHECK-DAG: [[C1:%.+]] = extractvalue { i33, i1 } [[S]], 1
107 // CHECK: [[QT:%.+]] = trunc i33 [[Q]] to i32
108 // CHECK: [[QTE:%.+]] = sext i32 [[QT]] to i33
109 // CHECK: [[C2:%.+]] = icmp ne i33 [[Q]], [[QTE]]
110 // CHECK: [[C3:%.+]] = or i1 [[C1]], [[C2]]
111 // CHECK: store i32 [[QT]], i32*
112 // CHECK: br i1 [[C3]]
113 int r;
114 if (__builtin_add_overflow(x, y, &r))
115 overflowed();
116 return r;
117 }
118
test_add_overflow_uint_uint_bool(unsigned x,unsigned y)119 _Bool test_add_overflow_uint_uint_bool(unsigned x, unsigned y) {
120 // CHECK-LABEL: define {{.*}} i1 @test_add_overflow_uint_uint_bool
121 // CHECK-NOT: ext
122 // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
123 // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
124 // CHECK-DAG: [[C1:%.+]] = extractvalue { i32, i1 } [[S]], 1
125 // CHECK: [[QT:%.+]] = trunc i32 [[Q]] to i1
126 // CHECK: [[QTE:%.+]] = zext i1 [[QT]] to i32
127 // CHECK: [[C2:%.+]] = icmp ne i32 [[Q]], [[QTE]]
128 // CHECK: [[C3:%.+]] = or i1 [[C1]], [[C2]]
129 // CHECK: [[QT2:%.+]] = zext i1 [[QT]] to i8
130 // CHECK: store i8 [[QT2]], i8*
131 // CHECK: br i1 [[C3]]
132 _Bool r;
133 if (__builtin_add_overflow(x, y, &r))
134 overflowed();
135 return r;
136 }
137
test_add_overflow_bool_bool_uint(_Bool x,_Bool y)138 unsigned test_add_overflow_bool_bool_uint(_Bool x, _Bool y) {
139 // CHECK-LABEL: define i32 @test_add_overflow_bool_bool_uint
140 // CHECK: [[XE:%.+]] = zext i1 %{{.+}} to i32
141 // CHECK: [[YE:%.+]] = zext i1 %{{.+}} to i32
142 // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[XE]], i32 [[YE]])
143 // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
144 // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
145 // CHECK: store i32 [[Q]], i32*
146 // CHECK: br i1 [[C]]
147 unsigned r;
148 if (__builtin_add_overflow(x, y, &r))
149 overflowed();
150 return r;
151 }
152
test_add_overflow_bool_bool_bool(_Bool x,_Bool y)153 _Bool test_add_overflow_bool_bool_bool(_Bool x, _Bool y) {
154 // CHECK-LABEL: define {{.*}} i1 @test_add_overflow_bool_bool_bool
155 // CHECK: [[S:%.+]] = call { i1, i1 } @llvm.uadd.with.overflow.i1(i1 %{{.+}}, i1 %{{.+}})
156 // CHECK-DAG: [[Q:%.+]] = extractvalue { i1, i1 } [[S]], 0
157 // CHECK-DAG: [[C:%.+]] = extractvalue { i1, i1 } [[S]], 1
158 // CHECK: [[QT2:%.+]] = zext i1 [[Q]] to i8
159 // CHECK: store i8 [[QT2]], i8*
160 // CHECK: br i1 [[C]]
161 _Bool r;
162 if (__builtin_add_overflow(x, y, &r))
163 overflowed();
164 return r;
165 }
166
test_add_overflow_volatile(int x,int y)167 int test_add_overflow_volatile(int x, int y) {
168 // CHECK-LABEL: define i32 @test_add_overflow_volatile
169 // CHECK: [[S:%.+]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
170 // CHECK-DAG: [[Q:%.+]] = extractvalue { i32, i1 } [[S]], 0
171 // CHECK-DAG: [[C:%.+]] = extractvalue { i32, i1 } [[S]], 1
172 // CHECK: store volatile i32 [[Q]], i32*
173 // CHECK: br i1 [[C]]
174 volatile int result;
175 if (__builtin_add_overflow(x, y, &result))
176 overflowed();
177 return result;
178 }
179
test_uadd_overflow(unsigned x,unsigned y)180 unsigned test_uadd_overflow(unsigned x, unsigned y) {
181 // CHECK: @test_uadd_overflow
182 // CHECK: %{{.+}} = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
183 unsigned result;
184 if (__builtin_uadd_overflow(x, y, &result))
185 return UnsignedErrorCode;
186 return result;
187 }
188
test_uaddl_overflow(unsigned long x,unsigned long y)189 unsigned long test_uaddl_overflow(unsigned long x, unsigned long y) {
190 // CHECK: @test_uaddl_overflow([[UL:i32|i64]] %x
191 // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.uadd.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})
192 unsigned long result;
193 if (__builtin_uaddl_overflow(x, y, &result))
194 return UnsignedLongErrorCode;
195 return result;
196 }
197
test_uaddll_overflow(unsigned long long x,unsigned long long y)198 unsigned long long test_uaddll_overflow(unsigned long long x, unsigned long long y) {
199 // CHECK: @test_uaddll_overflow
200 // CHECK: %{{.+}} = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})
201 unsigned long long result;
202 if (__builtin_uaddll_overflow(x, y, &result))
203 return UnsignedLongLongErrorCode;
204 return result;
205 }
206
test_usub_overflow(unsigned x,unsigned y)207 unsigned test_usub_overflow(unsigned x, unsigned y) {
208 // CHECK: @test_usub_overflow
209 // CHECK: %{{.+}} = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
210 unsigned result;
211 if (__builtin_usub_overflow(x, y, &result))
212 return UnsignedErrorCode;
213 return result;
214 }
215
test_usubl_overflow(unsigned long x,unsigned long y)216 unsigned long test_usubl_overflow(unsigned long x, unsigned long y) {
217 // CHECK: @test_usubl_overflow([[UL:i32|i64]] %x
218 // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.usub.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})
219 unsigned long result;
220 if (__builtin_usubl_overflow(x, y, &result))
221 return UnsignedLongErrorCode;
222 return result;
223 }
224
test_usubll_overflow(unsigned long long x,unsigned long long y)225 unsigned long long test_usubll_overflow(unsigned long long x, unsigned long long y) {
226 // CHECK: @test_usubll_overflow
227 // CHECK: %{{.+}} = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})
228 unsigned long long result;
229 if (__builtin_usubll_overflow(x, y, &result))
230 return UnsignedLongLongErrorCode;
231 return result;
232 }
233
test_umul_overflow(unsigned x,unsigned y)234 unsigned test_umul_overflow(unsigned x, unsigned y) {
235 // CHECK: @test_umul_overflow
236 // CHECK: %{{.+}} = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
237 unsigned result;
238 if (__builtin_umul_overflow(x, y, &result))
239 return UnsignedErrorCode;
240 return result;
241 }
242
test_umull_overflow(unsigned long x,unsigned long y)243 unsigned long test_umull_overflow(unsigned long x, unsigned long y) {
244 // CHECK: @test_umull_overflow([[UL:i32|i64]] %x
245 // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.umul.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})
246 unsigned long result;
247 if (__builtin_umull_overflow(x, y, &result))
248 return UnsignedLongErrorCode;
249 return result;
250 }
251
test_umulll_overflow(unsigned long long x,unsigned long long y)252 unsigned long long test_umulll_overflow(unsigned long long x, unsigned long long y) {
253 // CHECK: @test_umulll_overflow
254 // CHECK: %{{.+}} = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})
255 unsigned long long result;
256 if (__builtin_umulll_overflow(x, y, &result))
257 return UnsignedLongLongErrorCode;
258 return result;
259 }
260
test_sadd_overflow(int x,int y)261 int test_sadd_overflow(int x, int y) {
262 // CHECK: @test_sadd_overflow
263 // CHECK: %{{.+}} = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
264 int result;
265 if (__builtin_sadd_overflow(x, y, &result))
266 return IntErrorCode;
267 return result;
268 }
269
test_saddl_overflow(long x,long y)270 long test_saddl_overflow(long x, long y) {
271 // CHECK: @test_saddl_overflow([[UL:i32|i64]] %x
272 // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.sadd.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})
273 long result;
274 if (__builtin_saddl_overflow(x, y, &result))
275 return LongErrorCode;
276 return result;
277 }
278
test_saddll_overflow(long long x,long long y)279 long long test_saddll_overflow(long long x, long long y) {
280 // CHECK: @test_saddll_overflow
281 // CHECK: %{{.+}} = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})
282 long long result;
283 if (__builtin_saddll_overflow(x, y, &result))
284 return LongLongErrorCode;
285 return result;
286 }
287
test_ssub_overflow(int x,int y)288 int test_ssub_overflow(int x, int y) {
289 // CHECK: @test_ssub_overflow
290 // CHECK: %{{.+}} = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
291 int result;
292 if (__builtin_ssub_overflow(x, y, &result))
293 return IntErrorCode;
294 return result;
295 }
296
test_ssubl_overflow(long x,long y)297 long test_ssubl_overflow(long x, long y) {
298 // CHECK: @test_ssubl_overflow([[UL:i32|i64]] %x
299 // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.ssub.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})
300 long result;
301 if (__builtin_ssubl_overflow(x, y, &result))
302 return LongErrorCode;
303 return result;
304 }
305
test_ssubll_overflow(long long x,long long y)306 long long test_ssubll_overflow(long long x, long long y) {
307 // CHECK: @test_ssubll_overflow
308 // CHECK: %{{.+}} = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})
309 long long result;
310 if (__builtin_ssubll_overflow(x, y, &result))
311 return LongLongErrorCode;
312 return result;
313 }
314
test_smul_overflow(int x,int y)315 int test_smul_overflow(int x, int y) {
316 // CHECK: @test_smul_overflow
317 // CHECK: %{{.+}} = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %{{.+}}, i32 %{{.+}})
318 int result;
319 if (__builtin_smul_overflow(x, y, &result))
320 return IntErrorCode;
321 return result;
322 }
323
test_smull_overflow(long x,long y)324 long test_smull_overflow(long x, long y) {
325 // CHECK: @test_smull_overflow([[UL:i32|i64]] %x
326 // CHECK: %{{.+}} = call { [[UL]], i1 } @llvm.smul.with.overflow.[[UL]]([[UL]] %{{.+}}, [[UL]] %{{.+}})
327 long result;
328 if (__builtin_smull_overflow(x, y, &result))
329 return LongErrorCode;
330 return result;
331 }
332
test_smulll_overflow(long long x,long long y)333 long long test_smulll_overflow(long long x, long long y) {
334 // CHECK: @test_smulll_overflow
335 // CHECK: %{{.+}} = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %{{.+}}, i64 %{{.+}})
336 long long result;
337 if (__builtin_smulll_overflow(x, y, &result))
338 return LongLongErrorCode;
339 return result;
340 }
341