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 7197809 : convert_to_pointer_1 (tree type, tree expr, bool fold_p)
55 : {
56 7197809 : location_t loc = EXPR_LOCATION (expr);
57 7197809 : if (TREE_TYPE (expr) == type)
58 : return expr;
59 :
60 7197809 : switch (TREE_CODE (TREE_TYPE (expr)))
61 : {
62 6623390 : case POINTER_TYPE:
63 6623390 : case REFERENCE_TYPE:
64 6623390 : {
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 6623390 : addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (type));
68 6623390 : addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
69 :
70 6623390 : if (to_as == from_as)
71 6623390 : 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 574401 : case INTEGER_TYPE:
78 574401 : case ENUMERAL_TYPE:
79 574401 : case BOOLEAN_TYPE:
80 574401 : case BITINT_TYPE:
81 574401 : {
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 574401 : unsigned int pprec = TYPE_PRECISION (type);
87 574401 : unsigned int eprec = TYPE_PRECISION (TREE_TYPE (expr));
88 :
89 574401 : if (eprec != pprec)
90 512442 : expr
91 512442 : = maybe_fold_build1_loc (fold_p, loc, NOP_EXPR,
92 : lang_hooks.types.type_for_size (pprec, 0),
93 : expr);
94 : }
95 574401 : 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 425453153 : preserve_any_location_wrapper (tree result, tree orig_expr)
110 : {
111 425453153 : if (CONSTANT_CLASS_P (result) && location_wrapper_p (orig_expr))
112 : {
113 53054216 : if (result == TREE_OPERAND (orig_expr, 0))
114 : return orig_expr;
115 : else
116 26527987 : 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 7197809 : convert_to_pointer (tree type, tree expr)
127 : {
128 7197809 : 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 20162945 : convert_to_real_1 (tree type, tree expr, bool fold_p)
151 : {
152 20162945 : enum built_in_function fcode = builtin_mathfn_code (expr);
153 20162945 : tree itype = TREE_TYPE (expr);
154 20162945 : location_t loc = EXPR_LOCATION (expr);
155 :
156 20162945 : 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 20162494 : if (optimize
169 20162494 : && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
170 18125813 : || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
171 : {
172 11119557 : switch (fcode)
173 : {
174 : #define CASE_MATHFN(FN) case BUILT_IN_##FN: case BUILT_IN_##FN##L:
175 9777 : CASE_MATHFN (COSH)
176 9777 : CASE_MATHFN (EXP)
177 9777 : CASE_MATHFN (EXP10)
178 9777 : CASE_MATHFN (EXP2)
179 9777 : CASE_MATHFN (EXPM1)
180 9777 : CASE_MATHFN (GAMMA)
181 9777 : CASE_MATHFN (J0)
182 9777 : CASE_MATHFN (J1)
183 9777 : CASE_MATHFN (LGAMMA)
184 9777 : CASE_MATHFN (POW10)
185 9777 : CASE_MATHFN (SINH)
186 9777 : CASE_MATHFN (TGAMMA)
187 9777 : CASE_MATHFN (Y0)
188 9777 : 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 9777 : if (flag_errno_math)
193 : break;
194 24278 : gcc_fallthrough ();
195 24278 : CASE_MATHFN (ACOS)
196 24278 : CASE_MATHFN (ACOSH)
197 24278 : CASE_MATHFN (ASIN)
198 24278 : CASE_MATHFN (ASINH)
199 24278 : CASE_MATHFN (ATAN)
200 24278 : CASE_MATHFN (ATANH)
201 24278 : CASE_MATHFN (CBRT)
202 24278 : CASE_MATHFN (COS)
203 24278 : CASE_MATHFN (ERF)
204 24278 : CASE_MATHFN (ERFC)
205 24278 : CASE_MATHFN (LOG)
206 24278 : CASE_MATHFN (LOG10)
207 24278 : CASE_MATHFN (LOG2)
208 24278 : CASE_MATHFN (LOG1P)
209 24278 : CASE_MATHFN (SIN)
210 24278 : CASE_MATHFN (TAN)
211 24278 : CASE_MATHFN (TANH)
212 : /* The above functions are not safe to do this conversion. */
213 24278 : if (!flag_unsafe_math_optimizations)
214 : break;
215 5929 : gcc_fallthrough ();
216 5929 : CASE_MATHFN (SQRT)
217 5929 : CASE_MATHFN (FABS)
218 5929 : CASE_MATHFN (LOGB)
219 : #undef CASE_MATHFN
220 5929 : if (call_expr_nargs (expr) != 1
221 11858 : || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (expr, 0))))
222 : break;
223 5829 : {
224 5829 : tree arg0 = strip_float_extensions (CALL_EXPR_ARG (expr, 0));
225 5829 : 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 5829 : 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 5829 : if ((fcode == BUILT_IN_SQRT || fcode == BUILT_IN_SQRTL)
247 1427 : && !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 1365 : if (TYPE_MODE (type) != TYPE_MODE (newtype))
255 : break;
256 :
257 1364 : int p1 = REAL_MODE_FORMAT (TYPE_MODE (itype))->p;
258 1364 : int p2 = REAL_MODE_FORMAT (TYPE_MODE (newtype))->p;
259 1364 : if (p1 < p2 * 2 + 2)
260 : break;
261 : }
262 :
263 : /* Be careful about integer to fp conversions.
264 : These may overflow still. */
265 4475 : if (FLOAT_TYPE_P (TREE_TYPE (arg0))
266 4475 : && TYPE_PRECISION (newtype) < TYPE_PRECISION (itype)
267 5868 : && (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 20161101 : if (itype != type && FLOAT_TYPE_P (type))
287 20136109 : 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 69047 : case ABS_EXPR:
292 69047 : case NEGATE_EXPR:
293 69047 : if (!flag_rounding_math
294 69046 : && FLOAT_TYPE_P (itype)
295 99976 : && element_precision (type) < element_precision (itype))
296 : {
297 4149 : tree arg = convert_to_real_1 (type, TREE_OPERAND (expr, 0),
298 : fold_p);
299 4149 : return build1 (TREE_CODE (expr), type, arg);
300 : }
301 : break;
302 : default:
303 : break;
304 : }
305 :
306 20156952 : switch (TREE_CODE (TREE_TYPE (expr)))
307 : {
308 3312192 : 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 3312192 : return build1_loc (loc,
312 3312192 : (flag_float_store
313 3312083 : || DECIMAL_FLOAT_TYPE_P (type)
314 3294704 : || DECIMAL_FLOAT_TYPE_P (itype))
315 3312192 : ? CONVERT_EXPR : NOP_EXPR, type, expr);
316 :
317 16842669 : case INTEGER_TYPE:
318 16842669 : case ENUMERAL_TYPE:
319 16842669 : case BOOLEAN_TYPE:
320 16842669 : case BITINT_TYPE:
321 16842669 : 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 1075635 : convert_to_real (tree type, tree expr)
352 : {
353 1075635 : 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 19081317 : convert_to_real_maybe_fold (tree type, tree expr, bool dofold)
361 : {
362 19081317 : tree result
363 19081317 : = convert_to_real_1 (type, expr,
364 19081317 : dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
365 19081317 : 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 560333 : 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 560333 : tree typex = type;
379 :
380 : /* Can't do arithmetic in enumeral types
381 : so use an integer type that will hold the values. */
382 560333 : 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 560333 : if ((ex_form == PLUS_EXPR || ex_form == MINUS_EXPR)
389 363121 : && !TYPE_UNSIGNED (typex)
390 812734 : && 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 560199 : if (ex_form == MULT_EXPR
397 3933 : && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr))
398 562676 : && 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 560146 : 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 560146 : if (TYPE_UNSIGNED (TREE_TYPE (expr))
418 177159 : || (TYPE_UNSIGNED (TREE_TYPE (arg0))
419 88467 : && (TYPE_UNSIGNED (TREE_TYPE (arg1))
420 : || ex_form == LSHIFT_EXPR
421 73368 : || ex_form == RSHIFT_EXPR
422 : || ex_form == LROTATE_EXPR
423 72557 : || ex_form == RROTATE_EXPR))
424 161249 : || 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 721024 : || ((!(INTEGRAL_TYPE_P (TREE_TYPE (arg0))
432 160878 : && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0)))
433 73512 : || !(INTEGRAL_TYPE_P (TREE_TYPE (arg1))
434 73512 : && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1))))
435 159904 : && ((TYPE_PRECISION (TREE_TYPE (arg0)) * 2u
436 : > outprec)
437 1577 : || (TYPE_PRECISION (TREE_TYPE (arg1)) * 2u
438 : > outprec))
439 159806 : && (ex_form == PLUS_EXPR
440 : || ex_form == MINUS_EXPR
441 : || ex_form == MULT_EXPR)))
442 : {
443 519016 : if (!TYPE_UNSIGNED (typex))
444 262821 : typex = unsigned_type_for (typex);
445 : }
446 : else
447 : {
448 41130 : if (TYPE_UNSIGNED (typex))
449 29784 : 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 560146 : expr = maybe_fold_build2_loc (dofold, loc, ex_form, typex,
454 : convert (typex, arg0),
455 : convert (typex, arg1));
456 560146 : 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 227145629 : convert_to_integer_1 (tree type, tree expr, bool dofold)
474 : {
475 227145629 : enum tree_code ex_form = TREE_CODE (expr);
476 227145629 : tree intype = TREE_TYPE (expr);
477 227145629 : unsigned int inprec = element_precision (intype);
478 227145629 : unsigned int outprec = element_precision (type);
479 227145629 : 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 227145629 : if (!COMPLETE_TYPE_P (type))
484 : {
485 4 : error ("conversion to incomplete type");
486 4 : return error_mark_node;
487 : }
488 :
489 227145625 : if (ex_form == COMPOUND_EXPR)
490 : {
491 48210 : tree t = convert_to_integer_1 (type, TREE_OPERAND (expr, 1), dofold);
492 48210 : if (t == TREE_OPERAND (expr, 1))
493 : return expr;
494 45337 : return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR, TREE_TYPE (t),
495 90674 : 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 227097415 : if (optimize
504 227097415 : && (flag_unsafe_math_optimizations
505 212943930 : || (long_integer_type_node
506 212943930 : && outprec >= TYPE_PRECISION (long_integer_type_node))))
507 : {
508 83153004 : tree s_expr = strip_float_extensions (expr);
509 83153004 : tree s_intype = TREE_TYPE (s_expr);
510 83153004 : const enum built_in_function fcode = builtin_mathfn_code (s_expr);
511 83153004 : tree fn = 0;
512 :
513 83153004 : switch (fcode)
514 : {
515 38095 : CASE_FLT_FN (BUILT_IN_CEIL):
516 38095 : CASE_FLT_FN_FLOATN_NX (BUILT_IN_CEIL):
517 : /* Only convert in ISO C99 mode. */
518 38095 : if (!targetm.libc_has_function (function_c99_misc, intype))
519 : break;
520 38095 : if (outprec < TYPE_PRECISION (integer_type_node)
521 38095 : || (outprec == TYPE_PRECISION (integer_type_node)
522 73 : && !TYPE_UNSIGNED (type)))
523 20 : fn = mathfn_built_in (s_intype, BUILT_IN_ICEIL);
524 38075 : else if (outprec == TYPE_PRECISION (long_integer_type_node)
525 38075 : && !TYPE_UNSIGNED (type))
526 81 : fn = mathfn_built_in (s_intype, BUILT_IN_LCEIL);
527 37994 : else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
528 37994 : && !TYPE_UNSIGNED (type))
529 0 : fn = mathfn_built_in (s_intype, BUILT_IN_LLCEIL);
530 : break;
531 :
532 37700 : CASE_FLT_FN (BUILT_IN_FLOOR):
533 37700 : CASE_FLT_FN_FLOATN_NX (BUILT_IN_FLOOR):
534 : /* Only convert in ISO C99 mode. */
535 37700 : if (!targetm.libc_has_function (function_c99_misc, intype))
536 : break;
537 37700 : if (outprec < TYPE_PRECISION (integer_type_node)
538 37700 : || (outprec == TYPE_PRECISION (integer_type_node)
539 67 : && !TYPE_UNSIGNED (type)))
540 21 : fn = mathfn_built_in (s_intype, BUILT_IN_IFLOOR);
541 37679 : else if (outprec == TYPE_PRECISION (long_integer_type_node)
542 37679 : && !TYPE_UNSIGNED (type))
543 82 : fn = mathfn_built_in (s_intype, BUILT_IN_LFLOOR);
544 37597 : else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
545 37597 : && !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 478 : if (fn
605 478 : && call_expr_nargs (s_expr) == 1
606 956 : && SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (s_expr, 0))))
607 : {
608 468 : tree newexpr = build_call_expr (fn, 1, CALL_EXPR_ARG (s_expr, 0));
609 468 : return convert_to_integer_1 (type, newexpr, dofold);
610 : }
611 : }
612 :
613 : /* Convert (int)logb(d) -> ilogb(d). */
614 227096941 : if (optimize
615 213673546 : && flag_unsafe_math_optimizations
616 729619 : && !flag_trapping_math && !flag_errno_math && flag_finite_math_only
617 729465 : && integer_type_node
618 227826406 : && (outprec > TYPE_PRECISION (integer_type_node)
619 418240 : || (outprec == TYPE_PRECISION (integer_type_node)
620 214759 : && !TYPE_UNSIGNED (type))))
621 : {
622 379920 : tree s_expr = strip_float_extensions (expr);
623 379920 : tree s_intype = TREE_TYPE (s_expr);
624 379920 : const enum built_in_function fcode = builtin_mathfn_code (s_expr);
625 379920 : tree fn = 0;
626 :
627 379920 : 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 227096938 : switch (TREE_CODE (intype))
647 : {
648 845817 : case POINTER_TYPE:
649 845817 : case REFERENCE_TYPE:
650 845817 : if (integer_zerop (expr)
651 845817 : && !TREE_OVERFLOW (tree_strip_any_location_wrapper (expr)))
652 20384 : 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 825433 : if (!dofold)
659 162230 : return build1 (CONVERT_EXPR, type, expr);
660 663203 : expr = fold_build1 (CONVERT_EXPR,
661 : lang_hooks.types.type_for_size
662 : (TYPE_PRECISION (intype), 0),
663 : expr);
664 663203 : return fold_convert (type, expr);
665 :
666 225749626 : case INTEGER_TYPE:
667 225749626 : case ENUMERAL_TYPE:
668 225749626 : case BOOLEAN_TYPE:
669 225749626 : case OFFSET_TYPE:
670 225749626 : 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 225749626 : if (TREE_CODE_CLASS (ex_form) == tcc_comparison)
675 : {
676 2665421 : expr = copy_node (expr);
677 2665421 : TREE_TYPE (expr) = type;
678 2665421 : 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 223084205 : else if (outprec >= inprec)
686 : {
687 195417740 : 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 195417740 : if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (TREE_TYPE (expr))
699 195417740 : && !type_has_mode_precision_p (TREE_TYPE (expr)))
700 : code = CONVERT_EXPR;
701 : else
702 : code = NOP_EXPR;
703 :
704 195417740 : return maybe_fold_build1_loc (dofold, loc, code, type, expr);
705 : }
706 :
707 27666465 : 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 27666451 : else if (TREE_CODE (type) == ENUMERAL_TYPE
718 27666451 : || (TREE_CODE (type) != BITINT_TYPE
719 27502527 : && maybe_ne (outprec,
720 27502527 : GET_MODE_PRECISION (TYPE_MODE (type)))))
721 : {
722 1371444 : expr
723 1371444 : = convert_to_integer_1 (lang_hooks.types.type_for_mode
724 1371444 : (TYPE_MODE (type), TYPE_UNSIGNED (type)),
725 : expr, dofold);
726 1371444 : 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 26295007 : if (dofold)
750 21512958 : switch (ex_form)
751 : {
752 69955 : case RSHIFT_EXPR:
753 : /* We can pass truncation down through right shifting
754 : when the shift count is a nonpositive constant. */
755 69955 : if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
756 69955 : && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) <= 0)
757 55 : goto trunc1;
758 : break;
759 :
760 17312 : 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 17312 : if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
765 4357 : && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) >= 0
766 4325 : && TYPE_UNSIGNED (type)
767 19069 : && 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 1757 : if (wi::to_widest (TREE_OPERAND (expr, 1))
772 3514 : < TYPE_PRECISION (type))
773 : /* In this case, shifting is like multiplication. */
774 1734 : 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 24112 : case TRUNC_DIV_EXPR:
796 24112 : {
797 24112 : tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), NULL_TREE);
798 24112 : 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 24112 : if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
803 12973 : && 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 546 : && (TYPE_UNSIGNED (TREE_TYPE (arg0))
807 546 : == TYPE_UNSIGNED (TREE_TYPE (arg1)))
808 : /* Do not change the sign of the division. */
809 378 : && (TYPE_UNSIGNED (TREE_TYPE (expr))
810 378 : == TYPE_UNSIGNED (TREE_TYPE (arg0)))
811 : /* Either require unsigned division or a division by
812 : a constant that is not -1. */
813 24449 : && (TYPE_UNSIGNED (TREE_TYPE (arg0))
814 287 : || (TREE_CODE (arg1) == INTEGER_CST
815 162 : && !integer_all_onesp (arg1))))
816 : {
817 212 : tree tem = do_narrow (loc, ex_form, type, arg0, arg1,
818 : expr, inprec, outprec, dofold);
819 212 : if (tem)
820 : return tem;
821 : }
822 : break;
823 : }
824 :
825 44609 : case MAX_EXPR:
826 44609 : case MIN_EXPR:
827 44609 : case MULT_EXPR:
828 44609 : {
829 44609 : tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
830 44609 : 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 44609 : if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
836 24008 : && 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 49395 : && (TYPE_UNSIGNED (TREE_TYPE (arg0))
840 4786 : == TYPE_UNSIGNED (TREE_TYPE (arg1))))
841 4340 : goto trunc1;
842 : break;
843 : }
844 :
845 560141 : case PLUS_EXPR:
846 560141 : case MINUS_EXPR:
847 560141 : case BIT_AND_EXPR:
848 560141 : case BIT_IOR_EXPR:
849 560141 : case BIT_XOR_EXPR:
850 560141 : trunc1:
851 560141 : {
852 560141 : tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
853 560141 : 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 560141 : if (ex_form == MINUS_EXPR
858 13832 : && CONVERT_EXPR_P (arg0)
859 138 : && CONVERT_EXPR_P (arg1)
860 55 : && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg0, 0)))
861 560161 : && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg1, 0))))
862 : break;
863 :
864 560121 : tree tem = do_narrow (loc, ex_form, type, arg0, arg1,
865 : expr, inprec, outprec, dofold);
866 560121 : if (tem)
867 : return tem;
868 : }
869 : break;
870 :
871 57458 : case NEGATE_EXPR:
872 : /* Using unsigned arithmetic for signed types may hide overflow
873 : bugs. */
874 57458 : if (!TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (expr, 0)))
875 57458 : && sanitize_flags_p (SANITIZE_SI_OVERFLOW))
876 : break;
877 : /* Fall through. */
878 157846 : case BIT_NOT_EXPR:
879 : /* This is not correct for ABS_EXPR,
880 : since we must test the sign before truncation. */
881 157846 : {
882 : /* Do the arithmetic in type TYPEX,
883 : then convert result to TYPE. */
884 157846 : tree typex = type;
885 :
886 : /* Can't do arithmetic in enumeral types
887 : so use an integer type that will hold the values. */
888 157846 : 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 157846 : if (!TYPE_UNSIGNED (typex))
894 73414 : typex = unsigned_type_for (typex);
895 157846 : return convert (type,
896 157846 : fold_build1 (ex_form, typex,
897 : convert (typex,
898 157846 : TREE_OPERAND (expr, 0))));
899 : }
900 :
901 2203855 : CASE_CONVERT:
902 2203855 : {
903 2203855 : 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 2203855 : if (TREE_CODE (argtype) == VECTOR_TYPE
907 2203855 : && 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 2203855 : return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type));
914 :
915 90231 : 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 90231 : return
921 90231 : 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 23282906 : if (TREE_CODE (tree_strip_any_location_wrapper (expr)) == INTEGER_CST)
936 16210443 : return fold_convert (type, expr);
937 7072463 : return build1 (CONVERT_EXPR, type, expr);
938 :
939 458226 : case REAL_TYPE:
940 458226 : if (sanitize_flags_p (SANITIZE_FLOAT_CAST)
941 458226 : && 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 453248 : 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 36036 : case VECTOR_TYPE:
963 36036 : 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 36031 : 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 32268997 : convert_to_integer (tree type, tree expr)
988 : {
989 32268997 : 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 193456487 : convert_to_integer_maybe_fold (tree type, tree expr, bool dofold)
997 : {
998 193456487 : tree result
999 193456487 : = convert_to_integer_1 (type, expr,
1000 193456487 : dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
1001 193456487 : 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 480308 : convert_to_complex_1 (tree type, tree expr, bool fold_p)
1009 : {
1010 480308 : location_t loc = EXPR_LOCATION (expr);
1011 480308 : tree subtype = TREE_TYPE (type);
1012 :
1013 480308 : switch (TREE_CODE (TREE_TYPE (expr)))
1014 : {
1015 150669 : case REAL_TYPE:
1016 150669 : case FIXED_POINT_TYPE:
1017 150669 : case INTEGER_TYPE:
1018 150669 : case ENUMERAL_TYPE:
1019 150669 : case BOOLEAN_TYPE:
1020 150669 : case BITINT_TYPE:
1021 150669 : {
1022 150669 : tree real = convert (subtype, expr);
1023 150669 : tree imag = convert (subtype, integer_zero_node);
1024 150669 : if (error_operand_p (real) || error_operand_p (imag))
1025 1 : return error_mark_node;
1026 150668 : return build2 (COMPLEX_EXPR, type, real, imag);
1027 : }
1028 :
1029 329630 : case COMPLEX_TYPE:
1030 329630 : {
1031 329630 : tree elt_type = TREE_TYPE (TREE_TYPE (expr));
1032 :
1033 329630 : if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1034 : return expr;
1035 292137 : 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 292097 : else if (TREE_CODE (expr) == COMPLEX_EXPR)
1045 2371 : 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 289726 : expr = save_expr (expr);
1053 289726 : tree realp = maybe_fold_build1_loc (fold_p, loc, REALPART_EXPR,
1054 : TREE_TYPE (TREE_TYPE (expr)),
1055 : expr);
1056 289726 : tree imagp = maybe_fold_build1_loc (fold_p, loc, IMAGPART_EXPR,
1057 : TREE_TYPE (TREE_TYPE (expr)),
1058 : expr);
1059 289726 : 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 137496 : convert_to_complex (tree type, tree expr)
1081 : {
1082 137496 : 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 342772 : convert_to_complex_maybe_fold (tree type, tree expr, bool dofold)
1090 : {
1091 342772 : tree result
1092 342772 : = convert_to_complex_1 (type, expr,
1093 342772 : dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
1094 342772 : 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 103156180 : convert_to_vector (tree type, tree expr)
1101 : {
1102 103156180 : switch (TREE_CODE (TREE_TYPE (expr)))
1103 : {
1104 103156172 : case INTEGER_TYPE:
1105 103156172 : case VECTOR_TYPE:
1106 103156172 : 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 103156168 : 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 */
|