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 |
5 | |
6 | // CHECK-SANITIZE-ANYRECOVER: @[[UNSIGNED_INT:.*]] = {{.*}} c"'unsigned int'\00" } |
7 | // CHECK-SANITIZE-ANYRECOVER: @[[UNSIGNED_CHAR:.*]] = {{.*}} c"'unsigned char'\00" } |
8 | |
9 | // CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_UNSIGNED_TRUNCATION:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 1 } |
10 | // CHECK-SANITIZE-ANYRECOVER: @[[SIGNED_INT:.*]] = {{.*}} c"'int'\00" } |
11 | // CHECK-SANITIZE-ANYRECOVER: @[[LINE_200_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 200, i32 10 }, {{.*}}* @[[SIGNED_INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 2 } |
12 | // CHECK-SANITIZE-ANYRECOVER: @[[SIGNED_CHAR:.*]] = {{.*}} c"'signed char'\00" } |
13 | // CHECK-SANITIZE-ANYRECOVER: @[[LINE_300_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 300, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 } |
14 | // CHECK-SANITIZE-ANYRECOVER: @[[LINE_400_SIGNED_TRUNCATION:.*]] = {{.*}}, i32 400, i32 10 }, {{.*}}* @[[SIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 2 } |
15 | |
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 }, {{.*}}* @[[UINT32]], {{.*}}* @[[UINT8]], i8 1 } |
19 | |
20 | // ========================================================================== // |
21 | // The expected true-positives. These are implicit conversions, and they truncate. |
22 | // ========================================================================== // |
23 | |
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(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize |
34 | // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize |
35 | // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !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; |
42 | } |
43 | |
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(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize |
54 | // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize |
55 | // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !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; |
62 | } |
63 | |
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(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize |
74 | // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_300_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize |
75 | // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !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; |
82 | } |
83 | |
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(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize |
94 | // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400_SIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize |
95 | // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !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; |
102 | } |
103 | |
104 | // ========================================================================== // |
105 | // Check canonical type stuff |
106 | // ========================================================================== // |
107 | |
108 | typedef unsigned int uint32_t; |
109 | typedef unsigned char uint8_t; |
110 | |
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(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize |
121 | // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500_UNSIGNED_TRUNCATION]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize |
122 | // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !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; |
129 | } |
130 | |
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. |
136 | |
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; |
143 | } |
144 | |
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); |
152 | } |
153 | |
154 | // ========================================================================== // |
155 | // The expected true-negatives. |
156 | // ========================================================================== // |
157 | |
158 | // Sanitization is explicitly disabled. |
159 | // ========================================================================== // |
160 | |
161 | // CHECK-LABEL: @blacklist_0 |
162 | __attribute__((no_sanitize("undefined"))) unsigned char blacklist_0(unsigned int src) { |
163 | // We are not in "undefined" group, so that doesn't work. |
164 | // CHECK-SANITIZE: call |
165 | return src; |
166 | } |
167 | |
168 | // CHECK-LABEL: @blacklist_1 |
169 | __attribute__((no_sanitize("integer"))) unsigned char blacklist_1(unsigned int src) { |
170 | return src; |
171 | } |
172 | |
173 | // CHECK-LABEL: @blacklist_2 |
174 | __attribute__((no_sanitize("implicit-conversion"))) unsigned char blacklist_2(unsigned int src) { |
175 | return src; |
176 | } |
177 | |
178 | // CHECK-LABEL: @blacklist_3 |
179 | __attribute__((no_sanitize("implicit-integer-truncation"))) unsigned char blacklist_3(unsigned int src) { |
180 | return src; |
181 | } |
182 | |
183 | // Explicit truncating conversions. |
184 | // ========================================================================== // |
185 | |
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; |
189 | } |
190 | |
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; |
194 | } |
195 | |
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; |
199 | } |
200 | |
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; |
204 | } |
205 | |
206 | // Explicit NOP conversions. |
207 | // ========================================================================== // |
208 | |
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; |
212 | } |
213 | |
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; |
217 | } |
218 | |
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; |
222 | } |
223 | |
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; |
227 | } |
228 | |
229 | // upcasts. |
230 | // ========================================================================== // |
231 | |
232 | // CHECK-LABEL: @unsigned_char_to_unsigned_int |
233 | unsigned int unsigned_char_to_unsigned_int(unsigned char src) { |
234 | return src; |
235 | } |
236 | |
237 | // CHECK-LABEL: @signed_char_to_unsigned_int |
238 | unsigned int signed_char_to_unsigned_int(signed char src) { |
239 | return src; |
240 | } |
241 | |
242 | // CHECK-LABEL: @unsigned_char_to_signed_int |
243 | signed int unsigned_char_to_signed_int(unsigned char src) { |
244 | return src; |
245 | } |
246 | |
247 | // CHECK-LABEL: @signed_char_to_signed_int |
248 | signed int signed_char_to_signed_int(signed char src) { |
249 | return src; |
250 | } |
251 | |
252 | // Explicit upcasts. |
253 | // ========================================================================== // |
254 | |
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; |
258 | } |
259 | |
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; |
263 | } |
264 | |
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; |
268 | } |
269 | |
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; |
273 | } |
274 | |
275 | // conversions to to boolean type are not counted as truncation. |
276 | // ========================================================================== // |
277 | |
278 | // CHECK-LABEL: @unsigned_int_to_bool |
279 | _Bool unsigned_int_to_bool(unsigned int src) { |
280 | return src; |
281 | } |
282 | |
283 | // CHECK-LABEL: @signed_int_to_bool |
284 | _Bool signed_int_to_bool(signed int src) { |
285 | return src; |
286 | } |
287 | |
288 | // CHECK-LABEL: @explicit_unsigned_int_to_bool |
289 | _Bool explicit_unsigned_int_to_bool(unsigned int src) { |
290 | return (_Bool)src; |
291 | } |
292 | |
293 | // CHECK-LABEL: @explicit_signed_int_to_bool |
294 | _Bool explicit_signed_int_to_bool(signed int src) { |
295 | return (_Bool)src; |
296 | } |
297 | |
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 | // ========================================================================== // |
302 | |
303 | // CHECK-LABEL: @explicit_voidptr_to_unsigned_char |
304 | unsigned char explicit_voidptr_to_unsigned_char(void *src) { |
305 | return (unsigned char)src; |
306 | } |
307 | |
308 | // CHECK-LABEL: @explicit_voidptr_to_signed_char |
309 | signed char explicit_voidptr_to_signed_char(void *src) { |
310 | return (signed char)src; |
311 | } |
312 | |
313 | // Implicit truncating conversions from floating-point may result in precision loss. |
314 | // ========================================================================== // |
315 | |
316 | // CHECK-LABEL: @float_to_unsigned_int |
317 | unsigned int float_to_unsigned_int(float src) { |
318 | return src; |
319 | } |
320 | |
321 | // CHECK-LABEL: @float_to_signed_int |
322 | signed int float_to_signed_int(float src) { |
323 | return src; |
324 | } |
325 | |
326 | // CHECK-LABEL: @double_to_unsigned_int |
327 | unsigned int double_to_unsigned_int(double src) { |
328 | return src; |
329 | } |
330 | |
331 | // CHECK-LABEL: @double_to_signed_int |
332 | signed int double_to_signed_int(double src) { |
333 | return src; |
334 | } |
335 | |
336 | // Implicit truncating conversions between fp may result in precision loss. |
337 | // ========================================================================== // |
338 | |
339 | // CHECK-LABEL: @double_to_float |
340 | float double_to_float(double src) { |
341 | return src; |
342 | } |
343 | |