1 | // RUN: %clang -x c -fsanitize=implicit-unsigned-integer-truncation %s -DV0 -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK-V0,CHECK |
2 | // RUN: %clang -x c -fsanitize=implicit-unsigned-integer-truncation %s -DV1 -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK-V1,CHECK |
3 | // RUN: %clang -x c -fsanitize=implicit-unsigned-integer-truncation %s -DV2 -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK-V2,CHECK |
4 | // RUN: %clang -x c -fsanitize=implicit-unsigned-integer-truncation %s -DV3 -o %t && %run %t 2>&1 | FileCheck %s |
5 | // RUN: %clang -x c -fsanitize=implicit-unsigned-integer-truncation %s -DV4 -o %t && %run %t 2>&1 | FileCheck %s |
6 | // RUN: %clang -x c -fsanitize=implicit-unsigned-integer-truncation %s -DV5 -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK-V5,CHECK |
7 | // RUN: %clang -x c -fsanitize=implicit-unsigned-integer-truncation %s -DV6 -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK-V6,CHECK |
8 | // RUN: %clang -x c -fsanitize=implicit-unsigned-integer-truncation %s -DV7 -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK-V7,CHECK |
9 | |
10 | // RUN: %clangxx -x c++ -fsanitize=implicit-unsigned-integer-truncation %s -DV0 -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK-V0,CHECK |
11 | // RUN: %clangxx -x c++ -fsanitize=implicit-unsigned-integer-truncation %s -DV1 -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK-V1,CHECK |
12 | // RUN: %clangxx -x c++ -fsanitize=implicit-unsigned-integer-truncation %s -DV2 -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK-V2,CHECK |
13 | // RUN: %clangxx -x c++ -fsanitize=implicit-unsigned-integer-truncation %s -DV3 -o %t && %run %t 2>&1 | FileCheck %s |
14 | // RUN: %clangxx -x c++ -fsanitize=implicit-unsigned-integer-truncation %s -DV4 -o %t && %run %t 2>&1 | FileCheck %s |
15 | // RUN: %clangxx -x c++ -fsanitize=implicit-unsigned-integer-truncation %s -DV5 -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK-V5,CHECK |
16 | // RUN: %clangxx -x c++ -fsanitize=implicit-unsigned-integer-truncation %s -DV6 -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK-V6,CHECK |
17 | // RUN: %clangxx -x c++ -fsanitize=implicit-unsigned-integer-truncation %s -DV7 -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK-V7,CHECK |
18 | |
19 | #include <stdint.h> |
20 | #include <stdio.h> |
21 | |
22 | // Test plan: |
23 | // * Two types - int and char |
24 | // * Two signs - signed and unsigned |
25 | // * Square that - we have input and output types. |
26 | // Thus, there are total of (2*2)^2 == 16 tests. |
27 | // These are all the possible variations/combinations of casts. |
28 | // However, not all of them should result in the check. |
29 | // So here, we *only* check which should and which should not result in checks. |
30 | |
31 | uint32_t convert_unsigned_int_to_unsigned_int(uint32_t x) { |
32 | #line 100 |
33 | return x; |
34 | } |
35 | |
36 | uint8_t convert_unsigned_char_to_unsigned_char(uint8_t x) { |
37 | #line 200 |
38 | return x; |
39 | } |
40 | |
41 | int32_t convert_signed_int_to_signed_int(int32_t x) { |
42 | #line 300 |
43 | return x; |
44 | } |
45 | |
46 | int8_t convert_signed_char_to_signed_char(int8_t x) { |
47 | #line 400 |
48 | return x; |
49 | } |
50 | |
51 | uint8_t convert_unsigned_int_to_unsigned_char(uint32_t x) { |
52 | #line 500 |
53 | return x; |
54 | } |
55 | |
56 | uint32_t convert_unsigned_char_to_unsigned_int(uint8_t x) { |
57 | #line 600 |
58 | return x; |
59 | } |
60 | |
61 | int32_t convert_unsigned_char_to_signed_int(uint8_t x) { |
62 | #line 700 |
63 | return x; |
64 | } |
65 | |
66 | int32_t convert_signed_char_to_signed_int(int8_t x) { |
67 | #line 800 |
68 | return x; |
69 | } |
70 | |
71 | int32_t convert_unsigned_int_to_signed_int(uint32_t x) { |
72 | #line 900 |
73 | return x; |
74 | } |
75 | |
76 | uint32_t convert_signed_int_to_unsigned_int(int32_t x) { |
77 | #line 1000 |
78 | return x; |
79 | } |
80 | |
81 | uint8_t convert_signed_int_to_unsigned_char(int32_t x) { |
82 | #line 1100 |
83 | return x; |
84 | } |
85 | |
86 | uint8_t convert_signed_char_to_unsigned_char(int8_t x) { |
87 | #line 1200 |
88 | return x; |
89 | } |
90 | |
91 | int8_t convert_unsigned_char_to_signed_char(uint8_t x) { |
92 | #line 1300 |
93 | return x; |
94 | } |
95 | |
96 | uint32_t convert_signed_char_to_unsigned_int(int8_t x) { |
97 | #line 1400 |
98 | return x; |
99 | } |
100 | |
101 | int8_t convert_unsigned_int_to_signed_char(uint32_t x) { |
102 | #line 1500 |
103 | return x; |
104 | } |
105 | |
106 | int8_t convert_signed_int_to_signed_char(int32_t x) { |
107 | #line 1600 |
108 | return x; |
109 | } |
110 | |
111 | #line 1111 // !!! |
112 | |
113 | int main() { |
114 | fprintf(stderr, format: "TEST\n" ); |
115 | // CHECK-NOT: runtime error |
116 | // CHECK-LABEL: TEST |
117 | |
118 | // No bits set. |
119 | convert_unsigned_int_to_unsigned_int(x: 0); |
120 | convert_unsigned_char_to_unsigned_char(x: 0); |
121 | convert_signed_int_to_signed_int(x: 0); |
122 | convert_signed_char_to_signed_char(x: 0); |
123 | convert_unsigned_int_to_unsigned_char(x: 0); |
124 | convert_unsigned_char_to_unsigned_int(x: 0); |
125 | convert_unsigned_char_to_signed_int(x: 0); |
126 | convert_signed_char_to_signed_int(x: 0); |
127 | convert_unsigned_int_to_signed_int(x: 0); |
128 | convert_signed_int_to_unsigned_int(x: 0); |
129 | convert_signed_int_to_unsigned_char(x: 0); |
130 | convert_signed_char_to_unsigned_char(x: 0); |
131 | convert_unsigned_char_to_signed_char(x: 0); |
132 | convert_signed_char_to_unsigned_int(x: 0); |
133 | convert_unsigned_int_to_signed_char(x: 0); |
134 | convert_signed_int_to_signed_char(x: 0); |
135 | |
136 | // One lowest bit set. |
137 | convert_unsigned_int_to_unsigned_int(x: 1); |
138 | convert_unsigned_char_to_unsigned_char(x: 1); |
139 | convert_signed_int_to_signed_int(x: 1); |
140 | convert_signed_char_to_signed_char(x: 1); |
141 | convert_unsigned_int_to_unsigned_char(x: 1); |
142 | convert_unsigned_char_to_unsigned_int(x: 1); |
143 | convert_unsigned_char_to_signed_int(x: 1); |
144 | convert_signed_char_to_signed_int(x: 1); |
145 | convert_unsigned_int_to_signed_int(x: 1); |
146 | convert_signed_int_to_unsigned_int(x: 1); |
147 | convert_signed_int_to_unsigned_char(x: 1); |
148 | convert_signed_char_to_unsigned_char(x: 1); |
149 | convert_unsigned_char_to_signed_char(x: 1); |
150 | convert_signed_char_to_unsigned_int(x: 1); |
151 | convert_unsigned_int_to_signed_char(x: 1); |
152 | convert_signed_int_to_signed_char(x: 1); |
153 | |
154 | #if defined(V0) |
155 | // All source bits set. |
156 | convert_unsigned_int_to_unsigned_int((uint32_t)UINT32_MAX); |
157 | convert_unsigned_char_to_unsigned_char((uint8_t)UINT8_MAX); |
158 | convert_signed_int_to_signed_int((int32_t)(uint32_t)UINT32_MAX); |
159 | convert_signed_char_to_signed_char((int8_t)UINT8_MAX); |
160 | convert_unsigned_int_to_unsigned_char((uint32_t)UINT32_MAX); |
161 | // CHECK-V0: {{.*}}unsigned-integer-truncation.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned |
162 | convert_unsigned_char_to_unsigned_int((uint8_t)UINT8_MAX); |
163 | convert_unsigned_char_to_signed_int((uint8_t)UINT8_MAX); |
164 | convert_signed_char_to_signed_int((int8_t)UINT8_MAX); |
165 | convert_unsigned_int_to_signed_int((uint32_t)UINT32_MAX); |
166 | convert_signed_int_to_unsigned_int((int32_t)(uint32_t)UINT32_MAX); |
167 | convert_signed_int_to_unsigned_char((int32_t)(uint32_t)UINT32_MAX); |
168 | convert_signed_char_to_unsigned_char((int8_t)UINT8_MAX); |
169 | convert_unsigned_char_to_signed_char((uint8_t)UINT8_MAX); |
170 | convert_signed_char_to_unsigned_int((int8_t)UINT8_MAX); |
171 | convert_unsigned_int_to_signed_char((uint32_t)UINT32_MAX); |
172 | convert_signed_int_to_signed_char((int32_t)(uint32_t)UINT32_MAX); |
173 | #elif defined(V1) |
174 | // Source 'Sign' bit set. |
175 | convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MIN); |
176 | convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MIN); |
177 | convert_signed_int_to_signed_int((int32_t)(uint32_t)INT32_MIN); |
178 | convert_signed_char_to_signed_char((int8_t)INT8_MIN); |
179 | convert_unsigned_int_to_unsigned_char((uint32_t)INT32_MIN); |
180 | // CHECK-V1: {{.*}}unsigned-integer-truncation.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483648 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 0 (8-bit, unsigned) |
181 | convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MIN); |
182 | convert_unsigned_char_to_signed_int((uint8_t)INT8_MIN); |
183 | convert_signed_char_to_signed_int((int8_t)INT8_MIN); |
184 | convert_unsigned_int_to_signed_int((uint32_t)INT32_MIN); |
185 | convert_signed_int_to_unsigned_int((int32_t)(uint32_t)INT32_MIN); |
186 | convert_signed_int_to_unsigned_char((int32_t)(uint32_t)INT32_MIN); |
187 | convert_signed_char_to_unsigned_char((int8_t)INT8_MIN); |
188 | convert_unsigned_char_to_signed_char((uint8_t)INT8_MIN); |
189 | convert_signed_char_to_unsigned_int((int8_t)INT8_MIN); |
190 | convert_unsigned_int_to_signed_char((uint32_t)INT32_MIN); |
191 | convert_signed_int_to_signed_char((int32_t)(uint32_t)INT32_MIN); |
192 | #elif defined(V2) |
193 | // All bits except the source 'Sign' bit are set. |
194 | convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MAX); |
195 | convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MAX); |
196 | convert_signed_int_to_signed_int((int32_t)(uint32_t)INT32_MAX); |
197 | convert_signed_char_to_signed_char((int8_t)INT8_MAX); |
198 | convert_unsigned_int_to_unsigned_char((uint32_t)INT32_MAX); |
199 | // CHECK-V2: {{.*}}unsigned-integer-truncation.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483647 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) |
200 | convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MAX); |
201 | convert_unsigned_char_to_signed_int((uint8_t)INT8_MAX); |
202 | convert_signed_char_to_signed_int((int8_t)INT8_MAX); |
203 | convert_unsigned_int_to_signed_int((uint32_t)INT32_MAX); |
204 | convert_signed_int_to_unsigned_int((int32_t)(uint32_t)INT32_MAX); |
205 | convert_signed_int_to_unsigned_char((int32_t)(uint32_t)INT32_MAX); |
206 | convert_signed_char_to_unsigned_char((int8_t)INT8_MAX); |
207 | convert_unsigned_char_to_signed_char((uint8_t)INT8_MAX); |
208 | convert_signed_char_to_unsigned_int((int8_t)INT8_MAX); |
209 | convert_unsigned_int_to_signed_char((uint32_t)INT32_MAX); |
210 | convert_signed_int_to_signed_char((int32_t)(uint32_t)INT32_MAX); |
211 | #elif defined(V3) |
212 | // All destination bits set. |
213 | convert_unsigned_int_to_unsigned_int((uint32_t)UINT8_MAX); |
214 | convert_unsigned_char_to_unsigned_char((uint8_t)UINT8_MAX); |
215 | convert_signed_int_to_signed_int((int32_t)(uint32_t)UINT8_MAX); |
216 | convert_signed_char_to_signed_char((int8_t)UINT8_MAX); |
217 | convert_unsigned_int_to_unsigned_char((uint32_t)UINT8_MAX); |
218 | convert_unsigned_char_to_unsigned_int((uint8_t)UINT8_MAX); |
219 | convert_unsigned_char_to_signed_int((uint8_t)UINT8_MAX); |
220 | convert_signed_char_to_signed_int((int8_t)UINT8_MAX); |
221 | convert_unsigned_int_to_signed_int((uint32_t)UINT8_MAX); |
222 | convert_signed_int_to_unsigned_int((int32_t)(uint32_t)UINT8_MAX); |
223 | convert_signed_int_to_unsigned_char((int32_t)(uint32_t)UINT8_MAX); |
224 | convert_signed_char_to_unsigned_char((int8_t)UINT8_MAX); |
225 | convert_unsigned_char_to_signed_char((uint8_t)UINT8_MAX); |
226 | convert_signed_char_to_unsigned_int((int8_t)UINT8_MAX); |
227 | convert_unsigned_int_to_signed_char((uint32_t)UINT8_MAX); |
228 | convert_signed_int_to_signed_char((int32_t)(uint32_t)UINT8_MAX); |
229 | #elif defined(V4) |
230 | // Destination 'sign' bit set. |
231 | convert_unsigned_int_to_unsigned_int((uint32_t)(uint8_t)INT8_MIN); |
232 | convert_unsigned_char_to_unsigned_char((uint8_t)(uint8_t)INT8_MIN); |
233 | convert_signed_int_to_signed_int((int32_t)(uint32_t)(uint8_t)INT8_MIN); |
234 | convert_signed_char_to_signed_char((int8_t)(uint8_t)INT8_MIN); |
235 | convert_unsigned_int_to_unsigned_char((uint32_t)(uint8_t)INT8_MIN); |
236 | convert_unsigned_char_to_unsigned_int((uint8_t)(uint8_t)INT8_MIN); |
237 | convert_unsigned_char_to_signed_int((uint8_t)(uint8_t)INT8_MIN); |
238 | convert_signed_char_to_signed_int((int8_t)(uint8_t)INT8_MIN); |
239 | convert_unsigned_int_to_signed_int((uint32_t)(uint8_t)INT8_MIN); |
240 | convert_signed_int_to_unsigned_int((int32_t)(uint32_t)(uint8_t)INT8_MIN); |
241 | convert_signed_int_to_unsigned_char((int32_t)(uint32_t)(uint8_t)INT8_MIN); |
242 | convert_signed_char_to_unsigned_char((int8_t)(uint8_t)INT8_MIN); |
243 | convert_unsigned_char_to_signed_char((uint8_t)(uint8_t)INT8_MIN); |
244 | convert_signed_char_to_unsigned_int((int8_t)(uint8_t)INT8_MIN); |
245 | convert_unsigned_int_to_signed_char((uint32_t)(uint8_t)INT8_MIN); |
246 | convert_signed_int_to_signed_char((int32_t)(uint32_t)(uint8_t)INT8_MIN); |
247 | #elif defined(V5) |
248 | // All bits except the destination 'sign' bit are set. |
249 | convert_unsigned_int_to_unsigned_int((~((uint32_t)(uint8_t)INT8_MIN))); |
250 | convert_unsigned_char_to_unsigned_char((uint8_t)(uint8_t)INT8_MIN); |
251 | convert_signed_int_to_signed_int((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); |
252 | convert_signed_char_to_signed_char((int8_t)(uint8_t)INT8_MIN); |
253 | convert_unsigned_int_to_unsigned_char((~((uint32_t)(uint8_t)INT8_MIN))); |
254 | // CHECK-V5: {{.*}}unsigned-integer-truncation.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967167 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 127 (8-bit, unsigned) |
255 | convert_unsigned_char_to_unsigned_int((uint8_t)(uint8_t)INT8_MIN); |
256 | convert_unsigned_char_to_signed_int((uint8_t)(uint8_t)INT8_MIN); |
257 | convert_signed_char_to_signed_int((int8_t)(uint8_t)INT8_MIN); |
258 | convert_unsigned_int_to_signed_int((~((uint32_t)(uint8_t)INT8_MIN))); |
259 | convert_signed_int_to_unsigned_int((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); |
260 | convert_signed_int_to_unsigned_char((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); |
261 | convert_signed_char_to_unsigned_char((int8_t)(uint8_t)INT8_MIN); |
262 | convert_unsigned_char_to_signed_char((uint8_t)(uint8_t)INT8_MIN); |
263 | convert_signed_char_to_unsigned_int((int8_t)(uint8_t)INT8_MIN); |
264 | convert_unsigned_int_to_signed_char((~((uint32_t)(uint8_t)INT8_MIN))); |
265 | convert_signed_int_to_signed_char((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); |
266 | #elif defined(V6) |
267 | // Only the source and destination sign bits are set. |
268 | convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MIN); |
269 | convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MIN); |
270 | convert_signed_int_to_signed_int((int32_t)INT32_MIN); |
271 | convert_signed_char_to_signed_char((int8_t)INT8_MIN); |
272 | convert_unsigned_int_to_unsigned_char(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN)); |
273 | // CHECK-V6: {{.*}}unsigned-integer-truncation.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483776 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) |
274 | convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MIN); |
275 | convert_unsigned_char_to_signed_int((uint8_t)INT8_MIN); |
276 | convert_signed_char_to_signed_int((int8_t)INT8_MIN); |
277 | convert_unsigned_int_to_signed_int((uint32_t)INT32_MIN); |
278 | convert_signed_int_to_unsigned_int((uint32_t)INT32_MIN); |
279 | convert_signed_int_to_unsigned_char((int32_t)(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); |
280 | convert_signed_char_to_unsigned_char((int8_t)INT8_MIN); |
281 | convert_unsigned_char_to_signed_char((uint8_t)INT8_MIN); |
282 | convert_signed_char_to_unsigned_int((int8_t)INT8_MIN); |
283 | convert_unsigned_int_to_signed_char((((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); |
284 | convert_signed_int_to_signed_char((int32_t)(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); |
285 | #elif defined(V7) |
286 | // All bits except the source and destination sign bits are set. |
287 | convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MAX); |
288 | convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MAX); |
289 | convert_signed_int_to_signed_int((int32_t)INT32_MAX); |
290 | convert_signed_char_to_signed_char((int8_t)INT8_MAX); |
291 | convert_unsigned_int_to_unsigned_char(~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); |
292 | // CHECK-V7: {{.*}}unsigned-integer-truncation.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483519 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 127 (8-bit, unsigned) |
293 | convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MAX); |
294 | convert_unsigned_char_to_signed_int((uint8_t)INT8_MAX); |
295 | convert_signed_char_to_signed_int((int8_t)INT8_MAX); |
296 | convert_unsigned_int_to_signed_int((uint32_t)INT32_MAX); |
297 | convert_signed_int_to_unsigned_int((uint32_t)INT32_MAX); |
298 | convert_signed_int_to_unsigned_char((int32_t)(~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN)))); |
299 | convert_signed_char_to_unsigned_char((int8_t)INT8_MAX); |
300 | convert_unsigned_char_to_signed_char((uint8_t)INT8_MAX); |
301 | convert_signed_char_to_unsigned_int((int8_t)INT8_MAX); |
302 | convert_unsigned_int_to_signed_char(~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); |
303 | convert_signed_int_to_signed_char((int32_t)~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); |
304 | #else |
305 | #error Some V* needs to be defined! |
306 | #endif |
307 | |
308 | return 0; |
309 | } |
310 | |
311 | // CHECK-NOT: runtime error |
312 | |