Line data Source code
1 : /* Utility routines for data type conversion for GCC.
2 : Copyright (C) 1987-2026 Free Software Foundation, Inc.
3 :
4 : This file is part of GCC.
5 :
6 : GCC is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU General Public License as published by the Free
8 : Software Foundation; either version 3, or (at your option) any later
9 : version.
10 :
11 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with GCC; see the file COPYING3. If not see
18 : <http://www.gnu.org/licenses/>. */
19 :
20 :
21 : /* These routines are somewhat language-independent utility function
22 : intended to be called by the language-specific convert () functions. */
23 :
24 : #include "config.h"
25 : #include "system.h"
26 : #include "coretypes.h"
27 : #include "target.h"
28 : #include "tree.h"
29 : #include "diagnostic-core.h"
30 : #include "fold-const.h"
31 : #include "stor-layout.h"
32 : #include "convert.h"
33 : #include "langhooks.h"
34 : #include "builtins.h"
35 : #include "ubsan.h"
36 : #include "stringpool.h"
37 : #include "attribs.h"
38 : #include "asan.h"
39 : #include "selftest.h"
40 :
41 : #define maybe_fold_build1_loc(FOLD_P, LOC, CODE, TYPE, EXPR) \
42 : ((FOLD_P) ? fold_build1_loc (LOC, CODE, TYPE, EXPR) \
43 : : build1_loc (LOC, CODE, TYPE, EXPR))
44 : #define maybe_fold_build2_loc(FOLD_P, LOC, CODE, TYPE, EXPR1, EXPR2) \
45 : ((FOLD_P) ? fold_build2_loc (LOC, CODE, TYPE, EXPR1, EXPR2) \
46 : : build2_loc (LOC, CODE, TYPE, EXPR1, EXPR2))
47 :
48 : /* Convert EXPR to some pointer or reference type TYPE.
49 : EXPR must be pointer, reference, integer, enumeral, or literal zero;
50 : in other cases error is called. If FOLD_P is true, try to fold the
51 : expression. */
52 :
53 : static tree
54 7268636 : convert_to_pointer_1 (tree type, tree expr, bool fold_p)
55 : {
56 7268636 : location_t loc = EXPR_LOCATION (expr);
57 7268636 : if (TREE_TYPE (expr) == type)
58 : return expr;
59 :
60 7268636 : switch (TREE_CODE (TREE_TYPE (expr)))
61 : {
62 6685828 : case POINTER_TYPE:
63 6685828 : case REFERENCE_TYPE:
64 6685828 : {
65 : /* If the pointers point to different address spaces, conversion needs
66 : to be done via a ADDR_SPACE_CONVERT_EXPR instead of a NOP_EXPR. */
67 6685828 : addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (type));
68 6685828 : addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
69 :
70 6685828 : if (to_as == from_as)
71 6685828 : return maybe_fold_build1_loc (fold_p, loc, NOP_EXPR, type, expr);
72 : else
73 0 : return maybe_fold_build1_loc (fold_p, loc, ADDR_SPACE_CONVERT_EXPR,
74 : type, expr);
75 : }
76 :
77 582790 : case INTEGER_TYPE:
78 582790 : case ENUMERAL_TYPE:
79 582790 : case BOOLEAN_TYPE:
80 582790 : case BITINT_TYPE:
81 582790 : {
82 : /* If the input precision differs from the target pointer type
83 : precision, first convert the input expression to an integer type of
84 : the target precision. Some targets, e.g. VMS, need several pointer
85 : sizes to coexist so the latter isn't necessarily POINTER_SIZE. */
86 582790 : unsigned int pprec = TYPE_PRECISION (type);
87 582790 : unsigned int eprec = TYPE_PRECISION (TREE_TYPE (expr));
88 :
89 582790 : if (eprec != pprec)
90 520348 : expr
91 520348 : = maybe_fold_build1_loc (fold_p, loc, NOP_EXPR,
92 : lang_hooks.types.type_for_size (pprec, 0),
93 : expr);
94 : }
95 582790 : return maybe_fold_build1_loc (fold_p, loc, CONVERT_EXPR, type, expr);
96 :
97 18 : default:
98 18 : error ("cannot convert to a pointer type");
99 18 : return error_mark_node;
100 : }
101 : }
102 :
103 : /* Subroutine of the various convert_to_*_maybe_fold routines.
104 :
105 : If a location wrapper has been folded to a constant (presumably of
106 : a different type), re-wrap the new constant with a location wrapper. */
107 :
108 : tree
109 463754143 : preserve_any_location_wrapper (tree result, tree orig_expr)
110 : {
111 463754143 : if (CONSTANT_CLASS_P (result) && location_wrapper_p (orig_expr))
112 : {
113 56313896 : if (result == TREE_OPERAND (orig_expr, 0))
114 : return orig_expr;
115 : else
116 28157849 : return maybe_wrap_with_location (result, EXPR_LOCATION (orig_expr));
117 : }
118 :
119 : return result;
120 : }
121 :
122 : /* A wrapper around convert_to_pointer_1 that always folds the
123 : expression. */
124 :
125 : tree
126 7268636 : convert_to_pointer (tree type, tree expr)
127 : {
128 7268636 : return convert_to_pointer_1 (type, expr, true);
129 : }
130 :
131 : /* A wrapper around convert_to_pointer_1 that only folds the
132 : expression if DOFOLD, or if it is CONSTANT_CLASS_OR_WRAPPER_P. */
133 :
134 : tree
135 0 : convert_to_pointer_maybe_fold (tree type, tree expr, bool dofold)
136 : {
137 0 : tree result
138 0 : = convert_to_pointer_1 (type, expr,
139 0 : dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
140 0 : return preserve_any_location_wrapper (result, expr);
141 : }
142 :
143 : /* Convert EXPR to some floating-point type TYPE.
144 :
145 : EXPR must be float, fixed-point, integer, or enumeral;
146 : in other cases error is called. If FOLD_P is true, try to fold
147 : the expression. */
148 :
149 : static tree
150 21294787 : convert_to_real_1 (tree type, tree expr, bool fold_p)
151 : {
152 21294787 : enum built_in_function fcode = builtin_mathfn_code (expr);
153 21294787 : tree itype = TREE_TYPE (expr);
154 21294787 : location_t loc = EXPR_LOCATION (expr);
155 :
156 21294787 : if (TREE_CODE (expr) == COMPOUND_EXPR)
157 : {
158 451 : tree t = convert_to_real_1 (type, TREE_OPERAND (expr, 1), fold_p);
159 451 : if (t == TREE_OPERAND (expr, 1))
160 : return expr;
161 451 : return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR, TREE_TYPE (t),
162 902 : TREE_OPERAND (expr, 0), t);
163 : }
164 :
165 : /* Disable until we figure out how to decide whether the functions are
166 : present in runtime. */
167 : /* Convert (float)sqrt((double)x) where x is float into sqrtf(x) */
168 21294336 : if (optimize
169 21294336 : && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
170 19046593 : || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
171 : {
172 11796073 : switch (fcode)
173 : {
174 : #define CASE_MATHFN(FN) case BUILT_IN_##FN: case BUILT_IN_##FN##L:
175 13403 : CASE_MATHFN (COSH)
176 13403 : CASE_MATHFN (EXP)
177 13403 : CASE_MATHFN (EXP10)
178 13403 : CASE_MATHFN (EXP2)
179 13403 : CASE_MATHFN (EXPM1)
180 13403 : CASE_MATHFN (GAMMA)
181 13403 : CASE_MATHFN (J0)
182 13403 : CASE_MATHFN (J1)
183 13403 : CASE_MATHFN (LGAMMA)
184 13403 : CASE_MATHFN (POW10)
185 13403 : CASE_MATHFN (SINH)
186 13403 : CASE_MATHFN (TGAMMA)
187 13403 : CASE_MATHFN (Y0)
188 13403 : CASE_MATHFN (Y1)
189 : /* The above functions may set errno differently with float
190 : input or output so this transformation is not safe with
191 : -fmath-errno. */
192 13403 : if (flag_errno_math)
193 : break;
194 33084 : gcc_fallthrough ();
195 33084 : CASE_MATHFN (ACOS)
196 33084 : CASE_MATHFN (ACOSH)
197 33084 : CASE_MATHFN (ASIN)
198 33084 : CASE_MATHFN (ASINH)
199 33084 : CASE_MATHFN (ATAN)
200 33084 : CASE_MATHFN (ATANH)
201 33084 : CASE_MATHFN (CBRT)
202 33084 : CASE_MATHFN (COS)
203 33084 : CASE_MATHFN (ERF)
204 33084 : CASE_MATHFN (ERFC)
205 33084 : CASE_MATHFN (LOG)
206 33084 : CASE_MATHFN (LOG10)
207 33084 : CASE_MATHFN (LOG2)
208 33084 : CASE_MATHFN (LOG1P)
209 33084 : CASE_MATHFN (SIN)
210 33084 : CASE_MATHFN (TAN)
211 33084 : CASE_MATHFN (TANH)
212 : /* The above functions are not safe to do this conversion. */
213 33084 : if (!flag_unsafe_math_optimizations)
214 : break;
215 7507 : gcc_fallthrough ();
216 7507 : CASE_MATHFN (SQRT)
217 7507 : CASE_MATHFN (FABS)
218 7507 : CASE_MATHFN (LOGB)
219 : #undef CASE_MATHFN
220 7507 : if (call_expr_nargs (expr) != 1
221 15014 : || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (expr, 0))))
222 : break;
223 7407 : {
224 7407 : tree arg0 = strip_float_extensions (CALL_EXPR_ARG (expr, 0));
225 7407 : tree newtype = type;
226 :
227 : /* We have (outertype)sqrt((innertype)x). Choose the wider mode
228 : from the both as the safe type for operation. */
229 7407 : if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
230 5 : newtype = TREE_TYPE (arg0);
231 :
232 : /* We consider to convert
233 :
234 : (T1) sqrtT2 ((T2) exprT3)
235 : to
236 : (T1) sqrtT4 ((T4) exprT3)
237 :
238 : , where T1 is TYPE, T2 is ITYPE, T3 is TREE_TYPE (ARG0),
239 : and T4 is NEWTYPE. All those types are of floating-point types.
240 : T4 (NEWTYPE) should be narrower than T2 (ITYPE). This conversion
241 : is safe only if P1 >= P2*2+2, where P1 and P2 are precisions of
242 : T2 and T4. See the following URL for a reference:
243 : http://stackoverflow.com/questions/9235456/determining-
244 : floating-point-square-root
245 : */
246 7407 : if ((fcode == BUILT_IN_SQRT || fcode == BUILT_IN_SQRTL)
247 1945 : && !flag_unsafe_math_optimizations)
248 : {
249 : /* The following conversion is unsafe even the precision condition
250 : below is satisfied:
251 :
252 : (float) sqrtl ((long double) double_val) -> (float) sqrt (double_val)
253 : */
254 1883 : if (TYPE_MODE (type) != TYPE_MODE (newtype))
255 : break;
256 :
257 1882 : int p1 = REAL_MODE_FORMAT (TYPE_MODE (itype))->p;
258 1882 : int p2 = REAL_MODE_FORMAT (TYPE_MODE (newtype))->p;
259 1882 : if (p1 < p2 * 2 + 2)
260 : break;
261 : }
262 :
263 : /* Be careful about integer to fp conversions.
264 : These may overflow still. */
265 5535 : if (FLOAT_TYPE_P (TREE_TYPE (arg0))
266 5535 : && TYPE_PRECISION (newtype) < TYPE_PRECISION (itype)
267 6928 : && (TYPE_MODE (newtype) == TYPE_MODE (double_type_node)
268 943 : || TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
269 : {
270 1393 : tree fn = mathfn_built_in (newtype, fcode);
271 1393 : if (fn)
272 : {
273 1393 : tree arg = convert_to_real_1 (newtype, arg0, fold_p);
274 1393 : expr = build_call_expr (fn, 1, arg);
275 1393 : if (newtype == type)
276 : return expr;
277 : }
278 : }
279 : }
280 : default:
281 : break;
282 : }
283 : }
284 :
285 : /* Propagate the cast into the operation. */
286 21292943 : if (itype != type && FLOAT_TYPE_P (type))
287 21267951 : switch (TREE_CODE (expr))
288 : {
289 : /* Convert (float)-x into -(float)x. This is safe for
290 : round-to-nearest rounding mode when the inner type is float. */
291 74904 : case ABS_EXPR:
292 74904 : case NEGATE_EXPR:
293 74904 : if (!flag_rounding_math
294 74903 : && FLOAT_TYPE_P (itype)
295 110291 : && element_precision (type) < element_precision (itype))
296 : {
297 5667 : tree arg = convert_to_real_1 (type, TREE_OPERAND (expr, 0),
298 : fold_p);
299 5667 : return build1 (TREE_CODE (expr), type, arg);
300 : }
301 : break;
302 : default:
303 : break;
304 : }
305 :
306 21287276 : switch (TREE_CODE (TREE_TYPE (expr)))
307 : {
308 3814046 : case REAL_TYPE:
309 : /* Ignore the conversion if we don't need to store intermediate
310 : results and neither type is a decimal float. */
311 3814046 : return build1_loc (loc,
312 3814046 : (flag_float_store
313 3813937 : || DECIMAL_FLOAT_TYPE_P (type)
314 3796570 : || DECIMAL_FLOAT_TYPE_P (itype))
315 3814046 : ? CONVERT_EXPR : NOP_EXPR, type, expr);
316 :
317 17471139 : case INTEGER_TYPE:
318 17471139 : case ENUMERAL_TYPE:
319 17471139 : case BOOLEAN_TYPE:
320 17471139 : case BITINT_TYPE:
321 17471139 : return build1 (FLOAT_EXPR, type, expr);
322 :
323 0 : case FIXED_POINT_TYPE:
324 0 : return build1 (FIXED_CONVERT_EXPR, type, expr);
325 :
326 2064 : case COMPLEX_TYPE:
327 4128 : return convert (type,
328 2064 : maybe_fold_build1_loc (fold_p, loc, REALPART_EXPR,
329 : TREE_TYPE (TREE_TYPE (expr)),
330 2064 : expr));
331 :
332 4 : case POINTER_TYPE:
333 4 : case REFERENCE_TYPE:
334 4 : error ("pointer value used where a floating-point was expected");
335 4 : return error_mark_node;
336 :
337 11 : case VECTOR_TYPE:
338 11 : error ("vector value used where a floating-point was expected");
339 11 : return error_mark_node;
340 :
341 12 : default:
342 12 : error ("aggregate value used where a floating-point was expected");
343 12 : return error_mark_node;
344 : }
345 : }
346 :
347 : /* A wrapper around convert_to_real_1 that always folds the
348 : expression. */
349 :
350 : tree
351 1077399 : convert_to_real (tree type, tree expr)
352 : {
353 1077399 : return convert_to_real_1 (type, expr, true);
354 : }
355 :
356 : /* A wrapper around convert_to_real_1 that only folds the
357 : expression if DOFOLD, or if it is CONSTANT_CLASS_OR_WRAPPER_P. */
358 :
359 : tree
360 20209877 : convert_to_real_maybe_fold (tree type, tree expr, bool dofold)
361 : {
362 20209877 : tree result
363 40419754 : = convert_to_real_1 (type, expr,
364 18996071 : dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
365 20209877 : return preserve_any_location_wrapper (result, expr);
366 : }
367 :
368 : /* Try to narrow EX_FORM ARG0 ARG1 in narrowed arg types producing a
369 : result in TYPE. */
370 :
371 : static tree
372 645350 : do_narrow (location_t loc,
373 : enum tree_code ex_form, tree type, tree arg0, tree arg1,
374 : tree expr, unsigned inprec, unsigned outprec, bool dofold)
375 : {
376 : /* Do the arithmetic in type TYPEX,
377 : then convert result to TYPE. */
378 645350 : tree typex = type;
379 :
380 : /* Can't do arithmetic in enumeral types
381 : so use an integer type that will hold the values. */
382 645350 : if (TREE_CODE (typex) == ENUMERAL_TYPE)
383 0 : typex = lang_hooks.types.type_for_size (TYPE_PRECISION (typex),
384 0 : TYPE_UNSIGNED (typex));
385 :
386 : /* The type demotion below might cause doing unsigned arithmetic
387 : instead of signed, and thus hide overflow bugs. */
388 645350 : if ((ex_form == PLUS_EXPR || ex_form == MINUS_EXPR)
389 409461 : && !TYPE_UNSIGNED (typex)
390 916862 : && sanitize_flags_p (SANITIZE_SI_OVERFLOW))
391 : return NULL_TREE;
392 :
393 : /* Similarly for multiplication, but in that case it can be
394 : problematic even if typex is unsigned type - 0xffff * 0xffff
395 : overflows in int. */
396 645209 : if (ex_form == MULT_EXPR
397 4063 : && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr))
398 647693 : && sanitize_flags_p (SANITIZE_SI_OVERFLOW))
399 : return NULL_TREE;
400 :
401 : /* But now perhaps TYPEX is as wide as INPREC.
402 : In that case, do nothing special here.
403 : (Otherwise would recurse infinitely in convert. */
404 645156 : if (TYPE_PRECISION (typex) != inprec)
405 : {
406 : /* Don't do unsigned arithmetic where signed was wanted,
407 : or vice versa.
408 : Exception: if both of the original operands were
409 : unsigned then we can safely do the work as unsigned.
410 : Exception: shift operations take their type solely
411 : from the first argument.
412 : Exception: the LSHIFT_EXPR case above requires that
413 : we perform this operation unsigned lest we produce
414 : signed-overflow undefinedness.
415 : And we may need to do it as unsigned
416 : if we truncate to the original size. */
417 645156 : if (TYPE_UNSIGNED (TREE_TYPE (expr))
418 214860 : || (TYPE_UNSIGNED (TREE_TYPE (arg0))
419 120276 : && (TYPE_UNSIGNED (TREE_TYPE (arg1))
420 : || ex_form == LSHIFT_EXPR
421 104205 : || ex_form == RSHIFT_EXPR
422 : || ex_form == LROTATE_EXPR
423 103194 : || ex_form == RROTATE_EXPR))
424 197778 : || ex_form == LSHIFT_EXPR
425 : /* If we have !flag_wrapv, and either ARG0 or
426 : ARG1 is of a signed type, we have to do
427 : PLUS_EXPR, MINUS_EXPR or MULT_EXPR in an unsigned
428 : type in case the operation in outprec precision
429 : could overflow. Otherwise, we would introduce
430 : signed-overflow undefinedness. */
431 842562 : || ((!(INTEGRAL_TYPE_P (TREE_TYPE (arg0))
432 197406 : && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0)))
433 104149 : || !(INTEGRAL_TYPE_P (TREE_TYPE (arg1))
434 104149 : && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1))))
435 196432 : && ((TYPE_PRECISION (TREE_TYPE (arg0)) * 2u
436 : > outprec)
437 1858 : || (TYPE_PRECISION (TREE_TYPE (arg1)) * 2u
438 : > outprec))
439 196334 : && (ex_form == PLUS_EXPR
440 : || ex_form == MINUS_EXPR
441 : || ex_form == MULT_EXPR)))
442 : {
443 590872 : if (!TYPE_UNSIGNED (typex))
444 284588 : typex = unsigned_type_for (typex);
445 : }
446 : else
447 : {
448 54284 : if (TYPE_UNSIGNED (typex))
449 40241 : typex = signed_type_for (typex);
450 : }
451 : /* We should do away with all this once we have a proper
452 : type promotion/demotion pass, see PR45397. */
453 645156 : expr = maybe_fold_build2_loc (dofold, loc, ex_form, typex,
454 : convert (typex, arg0),
455 : convert (typex, arg1));
456 645156 : return convert (type, expr);
457 : }
458 :
459 : return NULL_TREE;
460 : }
461 :
462 : /* Convert EXPR to some integer (or enum) type TYPE.
463 :
464 : EXPR must be pointer, integer, discrete (enum, char, or bool), float,
465 : fixed-point or vector; in other cases error is called.
466 :
467 : If DOFOLD is TRUE, we try to simplify newly-created patterns by folding.
468 :
469 : The result of this is always supposed to be a newly created tree node
470 : not in use in any existing structure. */
471 :
472 : static tree
473 240877292 : convert_to_integer_1 (tree type, tree expr, bool dofold)
474 : {
475 240877770 : enum tree_code ex_form = TREE_CODE (expr);
476 240877770 : tree intype = TREE_TYPE (expr);
477 240877770 : unsigned int inprec = element_precision (intype);
478 240877770 : unsigned int outprec = element_precision (type);
479 240877770 : location_t loc = EXPR_LOCATION (expr);
480 :
481 : /* An INTEGER_TYPE cannot be incomplete, but an ENUMERAL_TYPE can
482 : be. Consider `enum E = { a, b = (enum E) 3 };'. */
483 240877770 : if (!COMPLETE_TYPE_P (type))
484 : {
485 4 : error ("conversion to incomplete type");
486 4 : return error_mark_node;
487 : }
488 :
489 240877766 : if (ex_form == COMPOUND_EXPR)
490 : {
491 48249 : tree t = convert_to_integer_1 (type, TREE_OPERAND (expr, 1), dofold);
492 48249 : if (t == TREE_OPERAND (expr, 1))
493 : return expr;
494 45376 : return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR, TREE_TYPE (t),
495 90752 : TREE_OPERAND (expr, 0), t);
496 : }
497 :
498 : /* Convert e.g. (long)round(d) -> lround(d). */
499 : /* If we're converting to char, we may encounter differing behavior
500 : between converting from double->char vs double->long->char.
501 : We're in "undefined" territory but we prefer to be conservative,
502 : so only proceed in "unsafe" math mode. */
503 240829517 : if (optimize
504 240829517 : && (flag_unsafe_math_optimizations
505 223685270 : || (long_integer_type_node
506 223685270 : && outprec >= TYPE_PRECISION (long_integer_type_node))))
507 : {
508 87558992 : tree s_expr = strip_float_extensions (expr);
509 87558992 : tree s_intype = TREE_TYPE (s_expr);
510 87558992 : const enum built_in_function fcode = builtin_mathfn_code (s_expr);
511 87558992 : tree fn = 0;
512 :
513 87558992 : switch (fcode)
514 : {
515 39496 : CASE_FLT_FN (BUILT_IN_CEIL):
516 39496 : CASE_FLT_FN_FLOATN_NX (BUILT_IN_CEIL):
517 : /* Only convert in ISO C99 mode. */
518 39496 : if (!targetm.libc_has_function (function_c99_misc, intype))
519 : break;
520 39496 : if (outprec < TYPE_PRECISION (integer_type_node)
521 39496 : || (outprec == TYPE_PRECISION (integer_type_node)
522 74 : && !TYPE_UNSIGNED (type)))
523 21 : fn = mathfn_built_in (s_intype, BUILT_IN_ICEIL);
524 39475 : else if (outprec == TYPE_PRECISION (long_integer_type_node)
525 39475 : && !TYPE_UNSIGNED (type))
526 81 : fn = mathfn_built_in (s_intype, BUILT_IN_LCEIL);
527 39394 : else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
528 39394 : && !TYPE_UNSIGNED (type))
529 0 : fn = mathfn_built_in (s_intype, BUILT_IN_LLCEIL);
530 : break;
531 :
532 39100 : CASE_FLT_FN (BUILT_IN_FLOOR):
533 39100 : CASE_FLT_FN_FLOATN_NX (BUILT_IN_FLOOR):
534 : /* Only convert in ISO C99 mode. */
535 39100 : if (!targetm.libc_has_function (function_c99_misc, intype))
536 : break;
537 39100 : if (outprec < TYPE_PRECISION (integer_type_node)
538 39100 : || (outprec == TYPE_PRECISION (integer_type_node)
539 67 : && !TYPE_UNSIGNED (type)))
540 21 : fn = mathfn_built_in (s_intype, BUILT_IN_IFLOOR);
541 39079 : else if (outprec == TYPE_PRECISION (long_integer_type_node)
542 39079 : && !TYPE_UNSIGNED (type))
543 82 : fn = mathfn_built_in (s_intype, BUILT_IN_LFLOOR);
544 38997 : else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
545 38997 : && !TYPE_UNSIGNED (type))
546 0 : fn = mathfn_built_in (s_intype, BUILT_IN_LLFLOOR);
547 : break;
548 :
549 107 : CASE_FLT_FN (BUILT_IN_ROUND):
550 107 : CASE_FLT_FN_FLOATN_NX (BUILT_IN_ROUND):
551 : /* Only convert in ISO C99 mode and with -fno-math-errno. */
552 107 : if (!targetm.libc_has_function (function_c99_misc, intype)
553 107 : || flag_errno_math)
554 : break;
555 104 : if (outprec < TYPE_PRECISION (integer_type_node)
556 104 : || (outprec == TYPE_PRECISION (integer_type_node)
557 24 : && !TYPE_UNSIGNED (type)))
558 25 : fn = mathfn_built_in (s_intype, BUILT_IN_IROUND);
559 79 : else if (outprec == TYPE_PRECISION (long_integer_type_node)
560 79 : && !TYPE_UNSIGNED (type))
561 74 : fn = mathfn_built_in (s_intype, BUILT_IN_LROUND);
562 5 : else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
563 5 : && !TYPE_UNSIGNED (type))
564 0 : fn = mathfn_built_in (s_intype, BUILT_IN_LLROUND);
565 : break;
566 :
567 95 : CASE_FLT_FN (BUILT_IN_NEARBYINT):
568 95 : CASE_FLT_FN_FLOATN_NX (BUILT_IN_NEARBYINT):
569 : /* Only convert nearbyint* if we can ignore math exceptions. */
570 95 : if (flag_trapping_math)
571 : break;
572 175 : gcc_fallthrough ();
573 175 : CASE_FLT_FN (BUILT_IN_RINT):
574 175 : CASE_FLT_FN_FLOATN_NX (BUILT_IN_RINT):
575 : /* Only convert in ISO C99 mode and with -fno-math-errno. */
576 175 : if (!targetm.libc_has_function (function_c99_misc, intype)
577 175 : || flag_errno_math)
578 : break;
579 175 : if (outprec < TYPE_PRECISION (integer_type_node)
580 175 : || (outprec == TYPE_PRECISION (integer_type_node)
581 25 : && !TYPE_UNSIGNED (type)))
582 25 : fn = mathfn_built_in (s_intype, BUILT_IN_IRINT);
583 150 : else if (outprec == TYPE_PRECISION (long_integer_type_node)
584 150 : && !TYPE_UNSIGNED (type))
585 150 : fn = mathfn_built_in (s_intype, BUILT_IN_LRINT);
586 0 : else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
587 0 : && !TYPE_UNSIGNED (type))
588 0 : fn = mathfn_built_in (s_intype, BUILT_IN_LLRINT);
589 : break;
590 :
591 14 : CASE_FLT_FN (BUILT_IN_TRUNC):
592 14 : CASE_FLT_FN_FLOATN_NX (BUILT_IN_TRUNC):
593 14 : if (call_expr_nargs (s_expr) != 1
594 14 : || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (s_expr, 0)))
595 26 : || (!flag_fp_int_builtin_inexact && flag_trapping_math))
596 : break;
597 6 : return convert_to_integer_1 (type, CALL_EXPR_ARG (s_expr, 0),
598 6 : dofold);
599 :
600 : default:
601 : break;
602 : }
603 :
604 479 : if (fn
605 479 : && call_expr_nargs (s_expr) == 1
606 958 : && SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (s_expr, 0))))
607 : {
608 469 : tree newexpr = build_call_expr (fn, 1, CALL_EXPR_ARG (s_expr, 0));
609 469 : return convert_to_integer_1 (type, newexpr, dofold);
610 : }
611 : }
612 :
613 : /* Convert (int)logb(d) -> ilogb(d). */
614 240829042 : if (optimize
615 224429244 : && flag_unsafe_math_optimizations
616 743977 : && !flag_trapping_math && !flag_errno_math && flag_finite_math_only
617 743822 : && integer_type_node
618 241572864 : && (outprec > TYPE_PRECISION (integer_type_node)
619 428384 : || (outprec == TYPE_PRECISION (integer_type_node)
620 216822 : && !TYPE_UNSIGNED (type))))
621 : {
622 384706 : tree s_expr = strip_float_extensions (expr);
623 384706 : tree s_intype = TREE_TYPE (s_expr);
624 384706 : const enum built_in_function fcode = builtin_mathfn_code (s_expr);
625 384706 : tree fn = 0;
626 :
627 384706 : switch (fcode)
628 : {
629 5 : CASE_FLT_FN (BUILT_IN_LOGB):
630 5 : fn = mathfn_built_in (s_intype, BUILT_IN_ILOGB);
631 5 : break;
632 :
633 : default:
634 : break;
635 : }
636 :
637 5 : if (fn
638 5 : && call_expr_nargs (s_expr) == 1
639 10 : && SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (s_expr, 0))))
640 : {
641 3 : tree newexpr = build_call_expr (fn, 1, CALL_EXPR_ARG (s_expr, 0));
642 3 : return convert_to_integer_1 (type, newexpr, dofold);
643 : }
644 : }
645 :
646 240829039 : switch (TREE_CODE (intype))
647 : {
648 875466 : case POINTER_TYPE:
649 875466 : case REFERENCE_TYPE:
650 875466 : if (integer_zerop (expr)
651 875466 : && !TREE_OVERFLOW (tree_strip_any_location_wrapper (expr)))
652 21657 : return build_int_cst (type, 0);
653 :
654 : /* Convert to an unsigned integer of the correct width first, and from
655 : there widen/truncate to the required type. Some targets support the
656 : coexistence of multiple valid pointer sizes, so fetch the one we need
657 : from the type. */
658 853809 : if (!dofold)
659 167957 : return build1 (CONVERT_EXPR, type, expr);
660 685852 : expr = fold_build1 (CONVERT_EXPR,
661 : lang_hooks.types.type_for_size
662 : (TYPE_PRECISION (intype), 0),
663 : expr);
664 685852 : return fold_convert (type, expr);
665 :
666 239432831 : case INTEGER_TYPE:
667 239432831 : case ENUMERAL_TYPE:
668 239432831 : case BOOLEAN_TYPE:
669 239432831 : case OFFSET_TYPE:
670 239432831 : case BITINT_TYPE:
671 : /* If this is a logical operation, which just returns 0 or 1, we can
672 : change the type of the expression. */
673 :
674 239432831 : if (TREE_CODE_CLASS (ex_form) == tcc_comparison)
675 : {
676 3009808 : expr = copy_node (expr);
677 3009808 : TREE_TYPE (expr) = type;
678 3009808 : return expr;
679 : }
680 :
681 : /* If we are widening the type, put in an explicit conversion.
682 : Similarly if we are not changing the width. After this, we know
683 : we are truncating EXPR. */
684 :
685 236423023 : else if (outprec >= inprec)
686 : {
687 207111947 : enum tree_code code;
688 :
689 : /* If the precision of the EXPR's type is K bits and the
690 : destination mode has more bits, and the sign is changing,
691 : it is not safe to use a NOP_EXPR. For example, suppose
692 : that EXPR's type is a 3-bit unsigned integer type, the
693 : TYPE is a 3-bit signed integer type, and the machine mode
694 : for the types is 8-bit QImode. In that case, the
695 : conversion necessitates an explicit sign-extension. In
696 : the signed-to-unsigned case the high-order bits have to
697 : be cleared. */
698 207111947 : if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (TREE_TYPE (expr))
699 207111947 : && !type_has_mode_precision_p (TREE_TYPE (expr)))
700 : code = CONVERT_EXPR;
701 : else
702 : code = NOP_EXPR;
703 :
704 207111947 : return maybe_fold_build1_loc (dofold, loc, code, type, expr);
705 : }
706 :
707 29311076 : else if (TREE_CODE (type) == ENUMERAL_TYPE && BITINT_TYPE_P (type))
708 : {
709 14 : expr = convert_to_integer_1 (TREE_TYPE (type), expr, dofold);
710 14 : return maybe_fold_build1_loc (dofold, loc, NOP_EXPR, type, expr);
711 : }
712 :
713 : /* If TYPE is an enumeral type or a type with a precision less
714 : than the number of bits in its mode, do the conversion to the
715 : type corresponding to its mode, then do a nop conversion
716 : to TYPE. */
717 29311062 : else if (TREE_CODE (type) == ENUMERAL_TYPE
718 29311062 : || (TREE_CODE (type) != BITINT_TYPE
719 29303335 : && maybe_ne (outprec,
720 29303335 : GET_MODE_PRECISION (TYPE_MODE (type)))))
721 : {
722 1445617 : expr
723 1445617 : = convert_to_integer_1 (lang_hooks.types.type_for_mode
724 1445617 : (TYPE_MODE (type), TYPE_UNSIGNED (type)),
725 : expr, dofold);
726 1445617 : return maybe_fold_build1_loc (dofold, loc, NOP_EXPR, type, expr);
727 : }
728 :
729 : /* Here detect when we can distribute the truncation down past some
730 : arithmetic. For example, if adding two longs and converting to an
731 : int, we can equally well convert both to ints and then add.
732 : For the operations handled here, such truncation distribution
733 : is always safe.
734 : It is desirable in these cases:
735 : 1) when truncating down to full-word from a larger size
736 : 2) when truncating takes no work.
737 : 3) when at least one operand of the arithmetic has been extended
738 : (as by C's default conversions). In this case we need two conversions
739 : if we do the arithmetic as already requested, so we might as well
740 : truncate both and then combine. Perhaps that way we need only one.
741 :
742 : Note that in general we cannot do the arithmetic in a type
743 : shorter than the desired result of conversion, even if the operands
744 : are both extended from a shorter type, because they might overflow
745 : if combined in that type. The exceptions to this--the times when
746 : two narrow values can be combined in their narrow type even to
747 : make a wider result--are handled by "shorten" in build_binary_op. */
748 :
749 27865445 : if (dofold)
750 22799167 : switch (ex_form)
751 : {
752 76231 : case RSHIFT_EXPR:
753 : /* We can pass truncation down through right shifting
754 : when the shift count is a nonpositive constant. */
755 76231 : if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
756 76231 : && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) <= 0)
757 55 : goto trunc1;
758 : break;
759 :
760 21564 : case LSHIFT_EXPR:
761 : /* We can pass truncation down through left shifting
762 : when the shift count is a nonnegative constant and
763 : the target type is unsigned. */
764 21564 : if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
765 5101 : && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) >= 0
766 5069 : && TYPE_UNSIGNED (type)
767 23522 : && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
768 : {
769 : /* If shift count is less than the width of the truncated type,
770 : really shift. */
771 1958 : if (wi::to_widest (TREE_OPERAND (expr, 1))
772 3916 : < TYPE_PRECISION (type))
773 : /* In this case, shifting is like multiplication. */
774 1935 : goto trunc1;
775 : else
776 : {
777 : /* If it is >= that width, result is zero.
778 : Handling this with trunc1 would give the wrong result:
779 : (int) ((long long) a << 32) is well defined (as 0)
780 : but (int) a << 32 is undefined and would get a
781 : warning. */
782 :
783 23 : tree t = build_int_cst (type, 0);
784 :
785 : /* If the original expression had side-effects, we must
786 : preserve it. */
787 23 : if (TREE_SIDE_EFFECTS (expr))
788 0 : return build2 (COMPOUND_EXPR, type, expr, t);
789 : else
790 : return t;
791 : }
792 : }
793 : break;
794 :
795 25366 : case TRUNC_DIV_EXPR:
796 25366 : {
797 25366 : tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), NULL_TREE);
798 25366 : tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), NULL_TREE);
799 :
800 : /* Don't distribute unless the output precision is at least as
801 : big as the actual inputs and it has the same signedness. */
802 25366 : if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
803 13896 : && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
804 : /* If signedness of arg0 and arg1 don't match,
805 : we can't necessarily find a type to compare them in. */
806 557 : && (TYPE_UNSIGNED (TREE_TYPE (arg0))
807 557 : == TYPE_UNSIGNED (TREE_TYPE (arg1)))
808 : /* Do not change the sign of the division. */
809 387 : && (TYPE_UNSIGNED (TREE_TYPE (expr))
810 387 : == TYPE_UNSIGNED (TREE_TYPE (arg0)))
811 : /* Either require unsigned division or a division by
812 : a constant that is not -1. */
813 25712 : && (TYPE_UNSIGNED (TREE_TYPE (arg0))
814 296 : || (TREE_CODE (arg1) == INTEGER_CST
815 163 : && !integer_all_onesp (arg1))))
816 : {
817 213 : tree tem = do_narrow (loc, ex_form, type, arg0, arg1,
818 : expr, inprec, outprec, dofold);
819 213 : if (tem)
820 : return tem;
821 : }
822 : break;
823 : }
824 :
825 45721 : case MAX_EXPR:
826 45721 : case MIN_EXPR:
827 45721 : case MULT_EXPR:
828 45721 : {
829 45721 : tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
830 45721 : tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
831 :
832 : /* Don't distribute unless the output precision is at least as
833 : big as the actual inputs. Otherwise, the comparison of the
834 : truncated values will be wrong. */
835 45721 : if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
836 24840 : && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
837 : /* If signedness of arg0 and arg1 don't match,
838 : we can't necessarily find a type to compare them in. */
839 50639 : && (TYPE_UNSIGNED (TREE_TYPE (arg0))
840 4918 : == TYPE_UNSIGNED (TREE_TYPE (arg1))))
841 4470 : goto trunc1;
842 : break;
843 : }
844 :
845 645157 : case PLUS_EXPR:
846 645157 : case MINUS_EXPR:
847 645157 : case BIT_AND_EXPR:
848 645157 : case BIT_IOR_EXPR:
849 645157 : case BIT_XOR_EXPR:
850 645157 : trunc1:
851 645157 : {
852 645157 : tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
853 645157 : tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
854 :
855 : /* Do not try to narrow operands of pointer subtraction;
856 : that will interfere with other folding. */
857 645157 : if (ex_form == MINUS_EXPR
858 17829 : && CONVERT_EXPR_P (arg0)
859 148 : && CONVERT_EXPR_P (arg1)
860 65 : && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg0, 0)))
861 645177 : && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg1, 0))))
862 : break;
863 :
864 645137 : tree tem = do_narrow (loc, ex_form, type, arg0, arg1,
865 : expr, inprec, outprec, dofold);
866 645137 : if (tem)
867 : return tem;
868 : }
869 : break;
870 :
871 90185 : case NEGATE_EXPR:
872 : /* Using unsigned arithmetic for signed types may hide overflow
873 : bugs. */
874 90185 : if (!TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (expr, 0)))
875 90185 : && sanitize_flags_p (SANITIZE_SI_OVERFLOW))
876 : break;
877 : /* Fall through. */
878 227305 : case BIT_NOT_EXPR:
879 : /* This is not correct for ABS_EXPR,
880 : since we must test the sign before truncation. */
881 227305 : {
882 : /* Do the arithmetic in type TYPEX,
883 : then convert result to TYPE. */
884 227305 : tree typex = type;
885 :
886 : /* Can't do arithmetic in enumeral types
887 : so use an integer type that will hold the values. */
888 227305 : if (TREE_CODE (typex) == ENUMERAL_TYPE)
889 0 : typex
890 0 : = lang_hooks.types.type_for_size (TYPE_PRECISION (typex),
891 0 : TYPE_UNSIGNED (typex));
892 :
893 227305 : if (!TYPE_UNSIGNED (typex))
894 115691 : typex = unsigned_type_for (typex);
895 227305 : return convert (type,
896 227305 : fold_build1 (ex_form, typex,
897 : convert (typex,
898 227305 : TREE_OPERAND (expr, 0))));
899 : }
900 :
901 2427716 : CASE_CONVERT:
902 2427716 : {
903 2427716 : tree argtype = TREE_TYPE (TREE_OPERAND (expr, 0));
904 : /* Don't introduce a "can't convert between vector values
905 : of different size" error. */
906 2427716 : if (TREE_CODE (argtype) == VECTOR_TYPE
907 2427716 : && maybe_ne (GET_MODE_SIZE (TYPE_MODE (argtype)),
908 0 : GET_MODE_SIZE (TYPE_MODE (type))))
909 : break;
910 : }
911 : /* If truncating after truncating, might as well do all at once.
912 : If truncating after extending, we may get rid of wasted work. */
913 2427716 : return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type));
914 :
915 102432 : case COND_EXPR:
916 : /* It is sometimes worthwhile to push the narrowing down through
917 : the conditional and never loses. A COND_EXPR may have a throw
918 : as one operand, which then has void type. Just leave void
919 : operands as they are. */
920 102432 : return
921 102432 : fold_build3 (COND_EXPR, type, TREE_OPERAND (expr, 0),
922 : VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 1)))
923 : ? TREE_OPERAND (expr, 1)
924 : : convert (type, TREE_OPERAND (expr, 1)),
925 : VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 2)))
926 : ? TREE_OPERAND (expr, 2)
927 : : convert (type, TREE_OPERAND (expr, 2)));
928 :
929 : default:
930 : break;
931 : }
932 :
933 : /* When parsing long initializers, we might end up with a lot of casts.
934 : Shortcut this. */
935 24462813 : if (TREE_CODE (tree_strip_any_location_wrapper (expr)) == INTEGER_CST)
936 16971657 : return fold_convert (type, expr);
937 7491156 : return build1 (CONVERT_EXPR, type, expr);
938 :
939 477347 : case REAL_TYPE:
940 477347 : if (sanitize_flags_p (SANITIZE_FLOAT_CAST)
941 477347 : && current_function_decl != NULL_TREE)
942 : {
943 4978 : expr = save_expr (expr);
944 4978 : tree check = ubsan_instrument_float_cast (loc, type, expr);
945 4978 : expr = build1 (FIX_TRUNC_EXPR, type, expr);
946 4978 : if (check == NULL_TREE)
947 : return expr;
948 4969 : return maybe_fold_build2_loc (dofold, loc, COMPOUND_EXPR,
949 : TREE_TYPE (expr), check, expr);
950 : }
951 : else
952 472369 : return build1 (FIX_TRUNC_EXPR, type, expr);
953 :
954 0 : case FIXED_POINT_TYPE:
955 0 : return build1 (FIXED_CONVERT_EXPR, type, expr);
956 :
957 7223 : case COMPLEX_TYPE:
958 7223 : expr = maybe_fold_build1_loc (dofold, loc, REALPART_EXPR,
959 : TREE_TYPE (TREE_TYPE (expr)), expr);
960 7223 : return convert (type, expr);
961 :
962 36162 : case VECTOR_TYPE:
963 36162 : if (!tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (expr))))
964 : {
965 5 : error ("cannot convert a vector of type %qT"
966 : " to type %qT which has different size",
967 5 : TREE_TYPE (expr), type);
968 5 : return error_mark_node;
969 : }
970 36157 : return build1 (VIEW_CONVERT_EXPR, type, expr);
971 :
972 10 : default:
973 10 : error ("aggregate value used where an integer was expected");
974 10 : return error_mark_node;
975 : }
976 : }
977 :
978 : /* Convert EXPR to some integer (or enum) type TYPE.
979 :
980 : EXPR must be pointer, integer, discrete (enum, char, or bool), float,
981 : fixed-point or vector; in other cases error is called.
982 :
983 : The result of this is always supposed to be a newly created tree node
984 : not in use in any existing structure. */
985 :
986 : tree
987 32832327 : convert_to_integer (tree type, tree expr)
988 : {
989 32832327 : return convert_to_integer_1 (type, expr, true);
990 : }
991 :
992 : /* A wrapper around convert_to_complex_1 that only folds the
993 : expression if DOFOLD, or if it is CONSTANT_CLASS_OR_WRAPPER_P. */
994 :
995 : tree
996 206551085 : convert_to_integer_maybe_fold (tree type, tree expr, bool dofold)
997 : {
998 206551085 : tree result
999 413102170 : = convert_to_integer_1 (type, expr,
1000 161534608 : dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
1001 206551085 : return preserve_any_location_wrapper (result, expr);
1002 : }
1003 :
1004 : /* Convert EXPR to the complex type TYPE in the usual ways. If FOLD_P is
1005 : true, try to fold the expression. */
1006 :
1007 : static tree
1008 542996 : convert_to_complex_1 (tree type, tree expr, bool fold_p)
1009 : {
1010 542996 : location_t loc = EXPR_LOCATION (expr);
1011 542996 : tree subtype = TREE_TYPE (type);
1012 :
1013 542996 : switch (TREE_CODE (TREE_TYPE (expr)))
1014 : {
1015 152639 : case REAL_TYPE:
1016 152639 : case FIXED_POINT_TYPE:
1017 152639 : case INTEGER_TYPE:
1018 152639 : case ENUMERAL_TYPE:
1019 152639 : case BOOLEAN_TYPE:
1020 152639 : case BITINT_TYPE:
1021 152639 : {
1022 152639 : tree real = convert (subtype, expr);
1023 152639 : tree imag = convert (subtype, integer_zero_node);
1024 152639 : if (error_operand_p (real) || error_operand_p (imag))
1025 1 : return error_mark_node;
1026 152638 : return build2 (COMPLEX_EXPR, type, real, imag);
1027 : }
1028 :
1029 390348 : case COMPLEX_TYPE:
1030 390348 : {
1031 390348 : tree elt_type = TREE_TYPE (TREE_TYPE (expr));
1032 :
1033 390348 : if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1034 : return expr;
1035 352855 : else if (TREE_CODE (expr) == COMPOUND_EXPR)
1036 : {
1037 40 : tree t = convert_to_complex_1 (type, TREE_OPERAND (expr, 1),
1038 : fold_p);
1039 40 : if (t == TREE_OPERAND (expr, 1))
1040 : return expr;
1041 40 : return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR,
1042 80 : TREE_TYPE (t), TREE_OPERAND (expr, 0), t);
1043 : }
1044 352815 : else if (TREE_CODE (expr) == COMPLEX_EXPR)
1045 2373 : return maybe_fold_build2_loc (fold_p, loc, COMPLEX_EXPR, type,
1046 : convert (subtype,
1047 : TREE_OPERAND (expr, 0)),
1048 : convert (subtype,
1049 : TREE_OPERAND (expr, 1)));
1050 : else
1051 : {
1052 350442 : expr = save_expr (expr);
1053 350442 : tree realp = maybe_fold_build1_loc (fold_p, loc, REALPART_EXPR,
1054 : TREE_TYPE (TREE_TYPE (expr)),
1055 : expr);
1056 350442 : tree imagp = maybe_fold_build1_loc (fold_p, loc, IMAGPART_EXPR,
1057 : TREE_TYPE (TREE_TYPE (expr)),
1058 : expr);
1059 350442 : return maybe_fold_build2_loc (fold_p, loc, COMPLEX_EXPR, type,
1060 : convert (subtype, realp),
1061 : convert (subtype, imagp));
1062 : }
1063 : }
1064 :
1065 3 : case POINTER_TYPE:
1066 3 : case REFERENCE_TYPE:
1067 3 : error ("pointer value used where a complex was expected");
1068 3 : return error_mark_node;
1069 :
1070 6 : default:
1071 6 : error ("aggregate value used where a complex was expected");
1072 6 : return error_mark_node;
1073 : }
1074 : }
1075 :
1076 : /* A wrapper around convert_to_complex_1 that always folds the
1077 : expression. */
1078 :
1079 : tree
1080 137560 : convert_to_complex (tree type, tree expr)
1081 : {
1082 137560 : return convert_to_complex_1 (type, expr, true);
1083 : }
1084 :
1085 : /* A wrapper around convert_to_complex_1 that only folds the
1086 : expression if DOFOLD, or if it is CONSTANT_CLASS_OR_WRAPPER_P. */
1087 :
1088 : tree
1089 405396 : convert_to_complex_maybe_fold (tree type, tree expr, bool dofold)
1090 : {
1091 405396 : tree result
1092 810792 : = convert_to_complex_1 (type, expr,
1093 391783 : dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
1094 405396 : return preserve_any_location_wrapper (result, expr);
1095 : }
1096 :
1097 : /* Convert EXPR to the vector type TYPE in the usual ways. */
1098 :
1099 : tree
1100 106233605 : convert_to_vector (tree type, tree expr)
1101 : {
1102 106233605 : switch (TREE_CODE (TREE_TYPE (expr)))
1103 : {
1104 106233597 : case INTEGER_TYPE:
1105 106233597 : case VECTOR_TYPE:
1106 106233597 : if (!tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (expr))))
1107 : {
1108 4 : error ("cannot convert a value of type %qT"
1109 : " to vector type %qT which has different size",
1110 4 : TREE_TYPE (expr), type);
1111 4 : return error_mark_node;
1112 : }
1113 106233593 : return build1 (VIEW_CONVERT_EXPR, type, expr);
1114 :
1115 8 : default:
1116 8 : error ("cannot convert value to a vector");
1117 8 : return error_mark_node;
1118 : }
1119 : }
1120 :
1121 : /* Convert EXPR to some fixed-point type TYPE.
1122 :
1123 : EXPR must be fixed-point, float, integer, or enumeral;
1124 : in other cases error is called. */
1125 :
1126 : tree
1127 0 : convert_to_fixed (tree type, tree expr)
1128 : {
1129 0 : if (integer_zerop (expr))
1130 : {
1131 0 : tree fixed_zero_node = build_fixed (type, FCONST0 (TYPE_MODE (type)));
1132 0 : return fixed_zero_node;
1133 : }
1134 0 : else if (integer_onep (expr) && ALL_SCALAR_ACCUM_MODE_P (TYPE_MODE (type)))
1135 : {
1136 0 : tree fixed_one_node = build_fixed (type, FCONST1 (TYPE_MODE (type)));
1137 0 : return fixed_one_node;
1138 : }
1139 :
1140 0 : switch (TREE_CODE (TREE_TYPE (expr)))
1141 : {
1142 0 : case FIXED_POINT_TYPE:
1143 0 : case INTEGER_TYPE:
1144 0 : case ENUMERAL_TYPE:
1145 0 : case BOOLEAN_TYPE:
1146 0 : case REAL_TYPE:
1147 0 : return build1 (FIXED_CONVERT_EXPR, type, expr);
1148 :
1149 0 : case COMPLEX_TYPE:
1150 0 : return convert (type,
1151 0 : fold_build1 (REALPART_EXPR,
1152 0 : TREE_TYPE (TREE_TYPE (expr)), expr));
1153 :
1154 0 : default:
1155 0 : error ("aggregate value used where a fixed-point was expected");
1156 0 : return error_mark_node;
1157 : }
1158 : }
1159 :
1160 : #if CHECKING_P
1161 :
1162 : namespace selftest {
1163 :
1164 : /* Selftests for conversions. */
1165 :
1166 : static void
1167 16 : test_convert_to_integer_maybe_fold (tree orig_type, tree new_type)
1168 : {
1169 : /* Calling convert_to_integer_maybe_fold on an INTEGER_CST. */
1170 :
1171 16 : tree orig_cst = build_int_cst (orig_type, 42);
1172 :
1173 : /* Verify that convert_to_integer_maybe_fold on a constant returns a new
1174 : constant of the new type, unless the types are the same, in which
1175 : case verify it's a no-op. */
1176 16 : {
1177 16 : tree result = convert_to_integer_maybe_fold (new_type,
1178 : orig_cst, false);
1179 16 : if (orig_type != new_type)
1180 : {
1181 8 : ASSERT_EQ (TREE_TYPE (result), new_type);
1182 8 : ASSERT_EQ (TREE_CODE (result), INTEGER_CST);
1183 : }
1184 : else
1185 8 : ASSERT_EQ (result, orig_cst);
1186 : }
1187 :
1188 : /* Calling convert_to_integer_maybe_fold on a location wrapper around
1189 : an INTEGER_CST.
1190 :
1191 : Verify that convert_to_integer_maybe_fold on a location wrapper
1192 : around a constant returns a new location wrapper around an equivalent
1193 : constant, both of the new type, unless the types are the same,
1194 : in which case the original wrapper should be returned. */
1195 16 : {
1196 16 : const location_t loc = BUILTINS_LOCATION;
1197 16 : tree wrapped_orig_cst = maybe_wrap_with_location (orig_cst, loc);
1198 16 : tree result
1199 16 : = convert_to_integer_maybe_fold (new_type, wrapped_orig_cst, false);
1200 16 : ASSERT_EQ (TREE_TYPE (result), new_type);
1201 16 : ASSERT_EQ (EXPR_LOCATION (result), loc);
1202 16 : ASSERT_TRUE (location_wrapper_p (result));
1203 16 : ASSERT_EQ (TREE_TYPE (TREE_OPERAND (result, 0)), new_type);
1204 16 : ASSERT_EQ (TREE_CODE (TREE_OPERAND (result, 0)), INTEGER_CST);
1205 :
1206 16 : if (orig_type == new_type)
1207 8 : ASSERT_EQ (result, wrapped_orig_cst);
1208 : }
1209 16 : }
1210 :
1211 : /* Verify that convert_to_integer_maybe_fold preserves locations. */
1212 :
1213 : static void
1214 4 : test_convert_to_integer_maybe_fold ()
1215 : {
1216 : /* char -> long. */
1217 4 : test_convert_to_integer_maybe_fold (char_type_node, long_integer_type_node);
1218 :
1219 : /* char -> char. */
1220 4 : test_convert_to_integer_maybe_fold (char_type_node, char_type_node);
1221 :
1222 : /* long -> char. */
1223 4 : test_convert_to_integer_maybe_fold (char_type_node, long_integer_type_node);
1224 :
1225 : /* long -> long. */
1226 4 : test_convert_to_integer_maybe_fold (long_integer_type_node,
1227 : long_integer_type_node);
1228 4 : }
1229 :
1230 : /* Run all of the selftests within this file. */
1231 :
1232 : void
1233 4 : convert_cc_tests ()
1234 : {
1235 4 : test_convert_to_integer_maybe_fold ();
1236 4 : }
1237 :
1238 : } // namespace selftest
1239 :
1240 : #endif /* CHECKING_P */
|