Revert "[llvm] Improve llvm.objectsize computation by computing GEP, alloca and mallo...
[llvm-project.git] / clang / test / CodeGen / catch-implicit-integer-truncations.c
blob8f991b14ad778910008112eb179cc39a4f6e8a2f
1 // RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK
2 // RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fno-sanitize-recover=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER,CHECK-SANITIZE-UNREACHABLE
3 // RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fsanitize-recover=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
4 // RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fsanitize-trap=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE
6 // CHECK-SANITIZE-ANYRECOVER: @[[UNSIGNED_INT:.*]] = {{.*}} c"'unsigned int'\00" }
7 // CHECK-SANITIZE-ANYRECOVER: @[[UNSIGNED_CHAR:.*]] = {{.*}} c"'unsigned char'\00" }
9 // CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 100, i32 10 }, ptr @[[UNSIGNED_INT]], ptr @[[UNSIGNED_CHAR]], i8 1, i32 0 }
10 // CHECK-SANITIZE-ANYRECOVER: @[[SIGNED_INT:.*]] = {{.*}} c"'int'\00" }
11 // CHECK-SANITIZE-ANYRECOVER: @[[LINE_200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 200, i32 10 }, ptr @[[SIGNED_INT]], ptr @[[UNSIGNED_CHAR]], i8 2, i32 0 }
12 // CHECK-SANITIZE-ANYRECOVER: @[[SIGNED_CHAR:.*]] = {{.*}} c"'signed char'\00" }
13 // CHECK-SANITIZE-ANYRECOVER: @[[LINE_300_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 300, i32 10 }, ptr @[[UNSIGNED_INT]], ptr @[[SIGNED_CHAR]], i8 2, i32 0 }
14 // CHECK-SANITIZE-ANYRECOVER: @[[LINE_400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 400, i32 10 }, ptr @[[SIGNED_INT]], ptr @[[SIGNED_CHAR]], i8 2, i32 0 }
16 // CHECK-SANITIZE-ANYRECOVER: @[[UINT32:.*]] = {{.*}} c"'uint32_t' (aka 'unsigned int')\00" }
17 // CHECK-SANITIZE-ANYRECOVER: @[[UINT8:.*]] = {{.*}} c"'uint8_t' (aka 'unsigned char')\00" }
18 // CHECK-SANITIZE-ANYRECOVER: @[[LINE_500_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 500, i32 10 }, ptr @[[UINT32]], ptr @[[UINT8]], i8 1, i32 0 }
20 // ========================================================================== //
21 // The expected true-positives. These are implicit conversions, and they truncate.
22 // ========================================================================== //
24 // CHECK-LABEL: @unsigned_int_to_unsigned_char
25 unsigned char unsigned_int_to_unsigned_char(unsigned int src) {
26 // CHECK: %[[DST:.*]] = trunc i32 %[[SRC:.*]] to i8
27 // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
28 // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
29 // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
30 // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
31 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
32 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
33 // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(ptr @[[LINE_100_UNSIGNED_TRUNCATION]], i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
34 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(ptr @[[LINE_100_UNSIGNED_TRUNCATION]], i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
35 // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 7){{.*}}, !nosanitize
36 // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
37 // CHECK-SANITIZE: [[CONT]]:
38 // CHECK-NEXT: ret i8 %[[DST]]
39 // CHECK-NEXT: }
40 #line 100
41 return src;
44 // CHECK-LABEL: @signed_int_to_unsigned_char
45 unsigned char signed_int_to_unsigned_char(signed int src) {
46 // CHECK: %[[DST:.*]] = trunc i32 %[[SRC:.*]] to i8
47 // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
48 // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
49 // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
50 // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
51 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
52 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
53 // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(ptr @[[LINE_200_SIGNED_TRUNCATION]], i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
54 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(ptr @[[LINE_200_SIGNED_TRUNCATION]], i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
55 // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 7){{.*}}, !nosanitize
56 // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
57 // CHECK-SANITIZE: [[CONT]]:
58 // CHECK-NEXT: ret i8 %[[DST]]
59 // CHECK-NEXT: }
60 #line 200
61 return src;
64 // CHECK-LABEL: @unsigned_int_to_signed_char
65 signed char unsigned_int_to_signed_char(unsigned int src) {
66 // CHECK: %[[DST:.*]] = trunc i32 %[[SRC:.*]] to i8
67 // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
68 // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
69 // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
70 // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
71 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
72 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
73 // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(ptr @[[LINE_300_SIGNED_TRUNCATION]], i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
74 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(ptr @[[LINE_300_SIGNED_TRUNCATION]], i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
75 // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 7){{.*}}, !nosanitize
76 // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
77 // CHECK-SANITIZE: [[CONT]]:
78 // CHECK-NEXT: ret i8 %[[DST]]
79 // CHECK-NEXT: }
80 #line 300
81 return src;
84 // CHECK-LABEL: @signed_int_to_signed_char
85 signed char signed_int_to_signed_char(signed int src) {
86 // CHECK: %[[DST:.*]] = trunc i32 %[[SRC:.*]] to i8
87 // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
88 // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
89 // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
90 // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
91 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
92 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
93 // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(ptr @[[LINE_400_SIGNED_TRUNCATION]], i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
94 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(ptr @[[LINE_400_SIGNED_TRUNCATION]], i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
95 // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 7){{.*}}, !nosanitize
96 // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
97 // CHECK-SANITIZE: [[CONT]]:
98 // CHECK-NEXT: ret i8 %[[DST]]
99 // CHECK-NEXT: }
100 #line 400
101 return src;
104 // ========================================================================== //
105 // Check canonical type stuff
106 // ========================================================================== //
108 typedef unsigned int uint32_t;
109 typedef unsigned char uint8_t;
111 // CHECK-LABEL: @uint32_to_uint8
112 uint8_t uint32_to_uint8(uint32_t src) {
113 // CHECK: %[[DST:.*]] = trunc i32 %[[SRC:.*]] to i8
114 // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
115 // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
116 // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
117 // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
118 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
119 // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
120 // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(ptr @[[LINE_500_UNSIGNED_TRUNCATION]], i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
121 // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(ptr @[[LINE_500_UNSIGNED_TRUNCATION]], i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
122 // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 7){{.*}}, !nosanitize
123 // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
124 // CHECK-SANITIZE: [[CONT]]:
125 // CHECK-NEXT: ret i8 %[[DST]]
126 // CHECK-NEXT: }
127 #line 500
128 return src;
131 // ========================================================================== //
132 // Check that explicit conversion does not interfere with implicit conversion
133 // ========================================================================== //
134 // These contain one implicit truncating conversion, and one explicit truncating conversion.
135 // We want to make sure that we still diagnose the implicit conversion.
137 // Implicit truncation after explicit truncation.
138 // CHECK-LABEL: @explicit_conversion_interference0
139 unsigned char explicit_conversion_interference0(unsigned int c) {
140 // CHECK-SANITIZE: %[[ANYEXT:.*]] = zext i8 %[[DST:.*]] to i16, !nosanitize
141 // CHECK-SANITIZE: call
142 return (unsigned short)c;
145 // Implicit truncation before explicit truncation.
146 // CHECK-LABEL: @explicit_conversion_interference1
147 unsigned char explicit_conversion_interference1(unsigned int c) {
148 // CHECK-SANITIZE: %[[ANYEXT:.*]] = zext i16 %[[DST:.*]] to i32, !nosanitize
149 // CHECK-SANITIZE: call
150 unsigned short b;
151 return (unsigned char)(b = c);
154 // ========================================================================== //
155 // The expected true-negatives.
156 // ========================================================================== //
158 // Sanitization is explicitly disabled.
159 // ========================================================================== //
161 // CHECK-LABEL: @ignorelist_0
162 __attribute__((no_sanitize("undefined"))) unsigned char ignorelist_0(unsigned int src) {
163 // We are not in "undefined" group, so that doesn't work.
164 // CHECK-SANITIZE: call
165 return src;
168 // CHECK-LABEL: @ignorelist_1
169 __attribute__((no_sanitize("integer"))) unsigned char ignorelist_1(unsigned int src) {
170 return src;
173 // CHECK-LABEL: @ignorelist_2
174 __attribute__((no_sanitize("implicit-conversion"))) unsigned char ignorelist_2(unsigned int src) {
175 return src;
178 // CHECK-LABEL: @ignorelist_3
179 __attribute__((no_sanitize("implicit-integer-truncation"))) unsigned char ignorelist_3(unsigned int src) {
180 return src;
183 // Explicit truncating conversions.
184 // ========================================================================== //
186 // CHECK-LABEL: @explicit_unsigned_int_to_unsigned_char
187 unsigned char explicit_unsigned_int_to_unsigned_char(unsigned int src) {
188 return (unsigned char)src;
191 // CHECK-LABEL: @explicit_signed_int_to_unsigned_char
192 unsigned char explicit_signed_int_to_unsigned_char(signed int src) {
193 return (unsigned char)src;
196 // CHECK-LABEL: @explicit_unsigned_int_to_signed_char
197 signed char explicit_unsigned_int_to_signed_char(unsigned int src) {
198 return (signed char)src;
201 // CHECK-LABEL: @explicit_signed_int_to_signed_char
202 signed char explicit_signed_int_to_signed_char(signed int src) {
203 return (signed char)src;
206 // Explicit NOP conversions.
207 // ========================================================================== //
209 // CHECK-LABEL: @explicit_unsigned_int_to_unsigned_int
210 unsigned int explicit_unsigned_int_to_unsigned_int(unsigned int src) {
211 return (unsigned int)src;
214 // CHECK-LABEL: @explicit_signed_int_to_signed_int
215 signed int explicit_signed_int_to_signed_int(signed int src) {
216 return (signed int)src;
219 // CHECK-LABEL: @explicit_unsigned_char_to_signed_char
220 unsigned char explicit_unsigned_char_to_signed_char(unsigned char src) {
221 return (unsigned char)src;
224 // CHECK-LABEL: @explicit_signed_char_to_signed_char
225 signed char explicit_signed_char_to_signed_char(signed char src) {
226 return (signed char)src;
229 // upcasts.
230 // ========================================================================== //
232 // CHECK-LABEL: @unsigned_char_to_unsigned_int
233 unsigned int unsigned_char_to_unsigned_int(unsigned char src) {
234 return src;
237 // CHECK-LABEL: @signed_char_to_unsigned_int
238 unsigned int signed_char_to_unsigned_int(signed char src) {
239 return src;
242 // CHECK-LABEL: @unsigned_char_to_signed_int
243 signed int unsigned_char_to_signed_int(unsigned char src) {
244 return src;
247 // CHECK-LABEL: @signed_char_to_signed_int
248 signed int signed_char_to_signed_int(signed char src) {
249 return src;
252 // Explicit upcasts.
253 // ========================================================================== //
255 // CHECK-LABEL: @explicit_unsigned_char_to_unsigned_int
256 unsigned int explicit_unsigned_char_to_unsigned_int(unsigned char src) {
257 return (unsigned int)src;
260 // CHECK-LABEL: @explicit_signed_char_to_unsigned_int
261 unsigned int explicit_signed_char_to_unsigned_int(signed char src) {
262 return (unsigned int)src;
265 // CHECK-LABEL: @explicit_unsigned_char_to_signed_int
266 signed int explicit_unsigned_char_to_signed_int(unsigned char src) {
267 return (signed int)src;
270 // CHECK-LABEL: @explicit_signed_char_to_signed_int
271 signed int explicit_signed_char_to_signed_int(signed char src) {
272 return (signed int)src;
275 // conversions to to boolean type are not counted as truncation.
276 // ========================================================================== //
278 // CHECK-LABEL: @unsigned_int_to_bool
279 _Bool unsigned_int_to_bool(unsigned int src) {
280 return src;
283 // CHECK-LABEL: @signed_int_to_bool
284 _Bool signed_int_to_bool(signed int src) {
285 return src;
288 // CHECK-LABEL: @explicit_unsigned_int_to_bool
289 _Bool explicit_unsigned_int_to_bool(unsigned int src) {
290 return (_Bool)src;
293 // CHECK-LABEL: @explicit_signed_int_to_bool
294 _Bool explicit_signed_int_to_bool(signed int src) {
295 return (_Bool)src;
298 // Explicit truncating conversions from pointer to a much-smaller integer.
299 // Can not have an implicit conversion from pointer to an integer.
300 // Can not have an implicit conversion between two enums.
301 // ========================================================================== //
303 // CHECK-LABEL: @explicit_voidptr_to_unsigned_char
304 unsigned char explicit_voidptr_to_unsigned_char(void *src) {
305 return (unsigned char)src;
308 // CHECK-LABEL: @explicit_voidptr_to_signed_char
309 signed char explicit_voidptr_to_signed_char(void *src) {
310 return (signed char)src;
313 // Implicit truncating conversions from floating-point may result in precision loss.
314 // ========================================================================== //
316 // CHECK-LABEL: @float_to_unsigned_int
317 unsigned int float_to_unsigned_int(float src) {
318 return src;
321 // CHECK-LABEL: @float_to_signed_int
322 signed int float_to_signed_int(float src) {
323 return src;
326 // CHECK-LABEL: @double_to_unsigned_int
327 unsigned int double_to_unsigned_int(double src) {
328 return src;
331 // CHECK-LABEL: @double_to_signed_int
332 signed int double_to_signed_int(double src) {
333 return src;
336 // Implicit truncating conversions between fp may result in precision loss.
337 // ========================================================================== //
339 // CHECK-LABEL: @double_to_float
340 float double_to_float(double src) {
341 return src;