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