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 7159331 : convert_to_pointer_1 (tree type, tree expr, bool fold_p)
55 : {
56 7159331 : location_t loc = EXPR_LOCATION (expr);
57 7159331 : if (TREE_TYPE (expr) == type)
58 : return expr;
59 :
60 7159331 : switch (TREE_CODE (TREE_TYPE (expr)))
61 : {
62 6590809 : case POINTER_TYPE:
63 6590809 : case REFERENCE_TYPE:
64 6590809 : {
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 6590809 : addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (type));
68 6590809 : addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
69 :
70 6590809 : if (to_as == from_as)
71 6590809 : 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 568504 : case INTEGER_TYPE:
78 568504 : case ENUMERAL_TYPE:
79 568504 : case BOOLEAN_TYPE:
80 568504 : case BITINT_TYPE:
81 568504 : {
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 568504 : unsigned int pprec = TYPE_PRECISION (type);
87 568504 : unsigned int eprec = TYPE_PRECISION (TREE_TYPE (expr));
88 :
89 568504 : if (eprec != pprec)
90 506706 : expr
91 506706 : = maybe_fold_build1_loc (fold_p, loc, NOP_EXPR,
92 : lang_hooks.types.type_for_size (pprec, 0),
93 : expr);
94 : }
95 568504 : 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 523709044 : preserve_any_location_wrapper (tree result, tree orig_expr)
110 : {
111 523709044 : if (CONSTANT_CLASS_P (result) && location_wrapper_p (orig_expr))
112 : {
113 60497244 : if (result == TREE_OPERAND (orig_expr, 0))
114 : return orig_expr;
115 : else
116 30249501 : 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 7159331 : convert_to_pointer (tree type, tree expr)
127 : {
128 7159331 : 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 20014852 : convert_to_real_1 (tree type, tree expr, bool fold_p)
151 : {
152 20014852 : enum built_in_function fcode = builtin_mathfn_code (expr);
153 20014852 : tree itype = TREE_TYPE (expr);
154 20014852 : location_t loc = EXPR_LOCATION (expr);
155 :
156 20014852 : 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 20014401 : if (optimize
169 20014401 : && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
170 18005383 : || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
171 : {
172 11022342 : switch (fcode)
173 : {
174 : #define CASE_MATHFN(FN) case BUILT_IN_##FN: case BUILT_IN_##FN##L:
175 9175 : CASE_MATHFN (COSH)
176 9175 : CASE_MATHFN (EXP)
177 9175 : CASE_MATHFN (EXP10)
178 9175 : CASE_MATHFN (EXP2)
179 9175 : CASE_MATHFN (EXPM1)
180 9175 : CASE_MATHFN (GAMMA)
181 9175 : CASE_MATHFN (J0)
182 9175 : CASE_MATHFN (J1)
183 9175 : CASE_MATHFN (LGAMMA)
184 9175 : CASE_MATHFN (POW10)
185 9175 : CASE_MATHFN (SINH)
186 9175 : CASE_MATHFN (TGAMMA)
187 9175 : CASE_MATHFN (Y0)
188 9175 : 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 9175 : if (flag_errno_math)
193 : break;
194 22816 : gcc_fallthrough ();
195 22816 : CASE_MATHFN (ACOS)
196 22816 : CASE_MATHFN (ACOSH)
197 22816 : CASE_MATHFN (ASIN)
198 22816 : CASE_MATHFN (ASINH)
199 22816 : CASE_MATHFN (ATAN)
200 22816 : CASE_MATHFN (ATANH)
201 22816 : CASE_MATHFN (CBRT)
202 22816 : CASE_MATHFN (COS)
203 22816 : CASE_MATHFN (ERF)
204 22816 : CASE_MATHFN (ERFC)
205 22816 : CASE_MATHFN (LOG)
206 22816 : CASE_MATHFN (LOG10)
207 22816 : CASE_MATHFN (LOG2)
208 22816 : CASE_MATHFN (LOG1P)
209 22816 : CASE_MATHFN (SIN)
210 22816 : CASE_MATHFN (TAN)
211 22816 : CASE_MATHFN (TANH)
212 : /* The above functions are not safe to do this conversion. */
213 22816 : if (!flag_unsafe_math_optimizations)
214 : break;
215 5667 : gcc_fallthrough ();
216 5667 : CASE_MATHFN (SQRT)
217 5667 : CASE_MATHFN (FABS)
218 5667 : CASE_MATHFN (LOGB)
219 : #undef CASE_MATHFN
220 5667 : if (call_expr_nargs (expr) != 1
221 11334 : || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (expr, 0))))
222 : break;
223 5567 : {
224 5567 : tree arg0 = strip_float_extensions (CALL_EXPR_ARG (expr, 0));
225 5567 : 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 5567 : 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 5567 : if ((fcode == BUILT_IN_SQRT || fcode == BUILT_IN_SQRTL)
247 1341 : && !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 1279 : if (TYPE_MODE (type) != TYPE_MODE (newtype))
255 : break;
256 :
257 1278 : int p1 = REAL_MODE_FORMAT (TYPE_MODE (itype))->p;
258 1278 : int p2 = REAL_MODE_FORMAT (TYPE_MODE (newtype))->p;
259 1278 : if (p1 < p2 * 2 + 2)
260 : break;
261 : }
262 :
263 : /* Be careful about integer to fp conversions.
264 : These may overflow still. */
265 4299 : if (FLOAT_TYPE_P (TREE_TYPE (arg0))
266 4299 : && TYPE_PRECISION (newtype) < TYPE_PRECISION (itype)
267 5692 : && (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 20013008 : if (itype != type && FLOAT_TYPE_P (type))
287 19988016 : 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 67807 : case ABS_EXPR:
292 67807 : case NEGATE_EXPR:
293 67807 : if (!flag_rounding_math
294 67806 : && FLOAT_TYPE_P (itype)
295 97856 : && element_precision (type) < element_precision (itype))
296 : {
297 3905 : tree arg = convert_to_real_1 (type, TREE_OPERAND (expr, 0),
298 : fold_p);
299 3905 : return build1 (TREE_CODE (expr), type, arg);
300 : }
301 : break;
302 : default:
303 : break;
304 : }
305 :
306 20009103 : switch (TREE_CODE (TREE_TYPE (expr)))
307 : {
308 3328072 : 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 3328072 : return build1_loc (loc,
312 3328072 : (flag_float_store
313 3327963 : || DECIMAL_FLOAT_TYPE_P (type)
314 3310589 : || DECIMAL_FLOAT_TYPE_P (itype))
315 3328072 : ? CONVERT_EXPR : NOP_EXPR, type, expr);
316 :
317 16678940 : case INTEGER_TYPE:
318 16678940 : case ENUMERAL_TYPE:
319 16678940 : case BOOLEAN_TYPE:
320 16678940 : case BITINT_TYPE:
321 16678940 : 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 1070527 : convert_to_real (tree type, tree expr)
352 : {
353 1070527 : 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 18938576 : convert_to_real_maybe_fold (tree type, tree expr, bool dofold)
361 : {
362 18938576 : tree result
363 18938576 : = convert_to_real_1 (type, expr,
364 18938576 : dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
365 18938576 : 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 716761 : 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 716761 : tree typex = type;
379 :
380 : /* Can't do arithmetic in enumeral types
381 : so use an integer type that will hold the values. */
382 716761 : 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 716761 : if ((ex_form == PLUS_EXPR || ex_form == MINUS_EXPR)
389 358087 : && !TYPE_UNSIGNED (typex)
390 964832 : && 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 716648 : if (ex_form == MULT_EXPR
397 3904 : && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr))
398 719098 : && 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 716609 : 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 716609 : if (TYPE_UNSIGNED (TREE_TYPE (expr))
418 182837 : || (TYPE_UNSIGNED (TREE_TYPE (arg0))
419 87214 : && (TYPE_UNSIGNED (TREE_TYPE (arg1))
420 : || ex_form == LSHIFT_EXPR
421 72406 : || ex_form == RSHIFT_EXPR
422 : || ex_form == LROTATE_EXPR
423 71749 : || ex_form == RROTATE_EXPR))
424 167372 : || 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 883610 : || ((!(INTEGRAL_TYPE_P (TREE_TYPE (arg0))
432 167001 : && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0)))
433 72704 : || !(INTEGRAL_TYPE_P (TREE_TYPE (arg1))
434 72704 : && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1))))
435 166027 : && ((TYPE_PRECISION (TREE_TYPE (arg0)) * 2u
436 : > outprec)
437 9794 : || (TYPE_PRECISION (TREE_TYPE (arg1)) * 2u
438 : > outprec))
439 165929 : && (ex_form == PLUS_EXPR
440 : || ex_form == MINUS_EXPR
441 : || ex_form == MULT_EXPR)))
442 : {
443 676312 : if (!TYPE_UNSIGNED (typex))
444 332540 : typex = unsigned_type_for (typex);
445 : }
446 : else
447 : {
448 40297 : if (TYPE_UNSIGNED (typex))
449 29450 : 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 716609 : expr = maybe_fold_build2_loc (dofold, loc, ex_form, typex,
454 : convert (typex, arg0),
455 : convert (typex, arg1));
456 716609 : 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 270482877 : convert_to_integer_1 (tree type, tree expr, bool dofold)
474 : {
475 270482877 : enum tree_code ex_form = TREE_CODE (expr);
476 270482877 : tree intype = TREE_TYPE (expr);
477 270482877 : unsigned int inprec = element_precision (intype);
478 270482877 : unsigned int outprec = element_precision (type);
479 270482877 : 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 270482877 : if (!COMPLETE_TYPE_P (type))
484 : {
485 4 : error ("conversion to incomplete type");
486 4 : return error_mark_node;
487 : }
488 :
489 270482873 : if (ex_form == COMPOUND_EXPR)
490 : {
491 48206 : tree t = convert_to_integer_1 (type, TREE_OPERAND (expr, 1), dofold);
492 48206 : if (t == TREE_OPERAND (expr, 1))
493 : return expr;
494 45333 : return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR, TREE_TYPE (t),
495 90666 : 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 270434667 : if (optimize
504 270434667 : && (flag_unsafe_math_optimizations
505 257082976 : || (long_integer_type_node
506 257082976 : && outprec >= TYPE_PRECISION (long_integer_type_node))))
507 : {
508 104009252 : tree s_expr = strip_float_extensions (expr);
509 104009252 : tree s_intype = TREE_TYPE (s_expr);
510 104009252 : const enum built_in_function fcode = builtin_mathfn_code (s_expr);
511 104009252 : tree fn = 0;
512 :
513 104009252 : switch (fcode)
514 : {
515 37689 : CASE_FLT_FN (BUILT_IN_CEIL):
516 37689 : CASE_FLT_FN_FLOATN_NX (BUILT_IN_CEIL):
517 : /* Only convert in ISO C99 mode. */
518 37689 : if (!targetm.libc_has_function (function_c99_misc, intype))
519 : break;
520 37689 : if (outprec < TYPE_PRECISION (integer_type_node)
521 37689 : || (outprec == TYPE_PRECISION (integer_type_node)
522 71 : && !TYPE_UNSIGNED (type)))
523 22 : fn = mathfn_built_in (s_intype, BUILT_IN_ICEIL);
524 37667 : else if (outprec == TYPE_PRECISION (long_integer_type_node)
525 37667 : && !TYPE_UNSIGNED (type))
526 81 : fn = mathfn_built_in (s_intype, BUILT_IN_LCEIL);
527 37586 : else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
528 37586 : && !TYPE_UNSIGNED (type))
529 0 : fn = mathfn_built_in (s_intype, BUILT_IN_LLCEIL);
530 : break;
531 :
532 37292 : CASE_FLT_FN (BUILT_IN_FLOOR):
533 37292 : CASE_FLT_FN_FLOATN_NX (BUILT_IN_FLOOR):
534 : /* Only convert in ISO C99 mode. */
535 37292 : if (!targetm.libc_has_function (function_c99_misc, intype))
536 : break;
537 37292 : if (outprec < TYPE_PRECISION (integer_type_node)
538 37292 : || (outprec == TYPE_PRECISION (integer_type_node)
539 63 : && !TYPE_UNSIGNED (type)))
540 21 : fn = mathfn_built_in (s_intype, BUILT_IN_IFLOOR);
541 37271 : else if (outprec == TYPE_PRECISION (long_integer_type_node)
542 37271 : && !TYPE_UNSIGNED (type))
543 82 : fn = mathfn_built_in (s_intype, BUILT_IN_LFLOOR);
544 37189 : else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
545 37189 : && !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 480 : if (fn
605 480 : && call_expr_nargs (s_expr) == 1
606 960 : && SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (s_expr, 0))))
607 : {
608 470 : tree newexpr = build_call_expr (fn, 1, CALL_EXPR_ARG (s_expr, 0));
609 470 : return convert_to_integer_1 (type, newexpr, dofold);
610 : }
611 : }
612 :
613 : /* Convert (int)logb(d) -> ilogb(d). */
614 270434191 : if (optimize
615 257812732 : && flag_unsafe_math_optimizations
616 729761 : && !flag_trapping_math && !flag_errno_math && flag_finite_math_only
617 729607 : && integer_type_node
618 271163798 : && (outprec > TYPE_PRECISION (integer_type_node)
619 417991 : || (outprec == TYPE_PRECISION (integer_type_node)
620 214534 : && !TYPE_UNSIGNED (type))))
621 : {
622 380289 : tree s_expr = strip_float_extensions (expr);
623 380289 : tree s_intype = TREE_TYPE (s_expr);
624 380289 : const enum built_in_function fcode = builtin_mathfn_code (s_expr);
625 380289 : tree fn = 0;
626 :
627 380289 : 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 270434188 : switch (TREE_CODE (intype))
647 : {
648 929400 : case POINTER_TYPE:
649 929400 : case REFERENCE_TYPE:
650 929400 : if (integer_zerop (expr)
651 929400 : && !TREE_OVERFLOW (tree_strip_any_location_wrapper (expr)))
652 19656 : 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 909744 : if (!dofold)
659 193533 : return build1 (CONVERT_EXPR, type, expr);
660 716211 : expr = fold_build1 (CONVERT_EXPR,
661 : lang_hooks.types.type_for_size
662 : (TYPE_PRECISION (intype), 0),
663 : expr);
664 716211 : return fold_convert (type, expr);
665 :
666 269008929 : case INTEGER_TYPE:
667 269008929 : case ENUMERAL_TYPE:
668 269008929 : case BOOLEAN_TYPE:
669 269008929 : case OFFSET_TYPE:
670 269008929 : 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 269008929 : if (TREE_CODE_CLASS (ex_form) == tcc_comparison)
675 : {
676 3285954 : expr = copy_node (expr);
677 3285954 : TREE_TYPE (expr) = type;
678 3285954 : 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 265722975 : else if (outprec >= inprec)
686 : {
687 230832745 : 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 230832745 : if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (TREE_TYPE (expr))
699 230832745 : && !type_has_mode_precision_p (TREE_TYPE (expr)))
700 : code = CONVERT_EXPR;
701 : else
702 : code = NOP_EXPR;
703 :
704 230832745 : return maybe_fold_build1_loc (dofold, loc, code, type, expr);
705 : }
706 :
707 : /* If TYPE is an enumeral type or a type with a precision less
708 : than the number of bits in its mode, do the conversion to the
709 : type corresponding to its mode, then do a nop conversion
710 : to TYPE. */
711 34890230 : else if (TREE_CODE (type) == ENUMERAL_TYPE
712 34890230 : || (TREE_CODE (type) != BITINT_TYPE
713 34712834 : && maybe_ne (outprec,
714 34712834 : GET_MODE_PRECISION (TYPE_MODE (type)))))
715 : {
716 4556945 : expr
717 4556945 : = convert_to_integer_1 (lang_hooks.types.type_for_mode
718 4556945 : (TYPE_MODE (type), TYPE_UNSIGNED (type)),
719 : expr, dofold);
720 4556945 : return maybe_fold_build1_loc (dofold, loc, NOP_EXPR, type, expr);
721 : }
722 :
723 : /* Here detect when we can distribute the truncation down past some
724 : arithmetic. For example, if adding two longs and converting to an
725 : int, we can equally well convert both to ints and then add.
726 : For the operations handled here, such truncation distribution
727 : is always safe.
728 : It is desirable in these cases:
729 : 1) when truncating down to full-word from a larger size
730 : 2) when truncating takes no work.
731 : 3) when at least one operand of the arithmetic has been extended
732 : (as by C's default conversions). In this case we need two conversions
733 : if we do the arithmetic as already requested, so we might as well
734 : truncate both and then combine. Perhaps that way we need only one.
735 :
736 : Note that in general we cannot do the arithmetic in a type
737 : shorter than the desired result of conversion, even if the operands
738 : are both extended from a shorter type, because they might overflow
739 : if combined in that type. The exceptions to this--the times when
740 : two narrow values can be combined in their narrow type even to
741 : make a wider result--are handled by "shorten" in build_binary_op. */
742 :
743 30333285 : if (dofold)
744 24523432 : switch (ex_form)
745 : {
746 167723 : case RSHIFT_EXPR:
747 : /* We can pass truncation down through right shifting
748 : when the shift count is a nonpositive constant. */
749 167723 : if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
750 167723 : && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) <= 0)
751 55 : goto trunc1;
752 : break;
753 :
754 16683 : case LSHIFT_EXPR:
755 : /* We can pass truncation down through left shifting
756 : when the shift count is a nonnegative constant and
757 : the target type is unsigned. */
758 16683 : if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
759 4094 : && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) >= 0
760 4062 : && TYPE_UNSIGNED (type)
761 18286 : && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
762 : {
763 : /* If shift count is less than the width of the truncated type,
764 : really shift. */
765 1603 : if (wi::to_widest (TREE_OPERAND (expr, 1))
766 3206 : < TYPE_PRECISION (type))
767 : /* In this case, shifting is like multiplication. */
768 1580 : goto trunc1;
769 : else
770 : {
771 : /* If it is >= that width, result is zero.
772 : Handling this with trunc1 would give the wrong result:
773 : (int) ((long long) a << 32) is well defined (as 0)
774 : but (int) a << 32 is undefined and would get a
775 : warning. */
776 :
777 23 : tree t = build_int_cst (type, 0);
778 :
779 : /* If the original expression had side-effects, we must
780 : preserve it. */
781 23 : if (TREE_SIDE_EFFECTS (expr))
782 0 : return build2 (COMPOUND_EXPR, type, expr, t);
783 : else
784 : return t;
785 : }
786 : }
787 : break;
788 :
789 23732 : case TRUNC_DIV_EXPR:
790 23732 : {
791 23732 : tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), NULL_TREE);
792 23732 : tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), NULL_TREE);
793 :
794 : /* Don't distribute unless the output precision is at least as
795 : big as the actual inputs and it has the same signedness. */
796 23732 : if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
797 12679 : && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
798 : /* If signedness of arg0 and arg1 don't match,
799 : we can't necessarily find a type to compare them in. */
800 511 : && (TYPE_UNSIGNED (TREE_TYPE (arg0))
801 511 : == TYPE_UNSIGNED (TREE_TYPE (arg1)))
802 : /* Do not change the sign of the division. */
803 345 : && (TYPE_UNSIGNED (TREE_TYPE (expr))
804 345 : == TYPE_UNSIGNED (TREE_TYPE (arg0)))
805 : /* Either require unsigned division or a division by
806 : a constant that is not -1. */
807 24036 : && (TYPE_UNSIGNED (TREE_TYPE (arg0))
808 282 : || (TREE_CODE (arg1) == INTEGER_CST
809 161 : && !integer_all_onesp (arg1))))
810 : {
811 183 : tree tem = do_narrow (loc, ex_form, type, arg0, arg1,
812 : expr, inprec, outprec, dofold);
813 183 : if (tem)
814 : return tem;
815 : }
816 : break;
817 : }
818 :
819 44179 : case MAX_EXPR:
820 44179 : case MIN_EXPR:
821 44179 : case MULT_EXPR:
822 44179 : {
823 44179 : tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
824 44179 : tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
825 :
826 : /* Don't distribute unless the output precision is at least as
827 : big as the actual inputs. Otherwise, the comparison of the
828 : truncated values will be wrong. */
829 44179 : if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
830 23782 : && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
831 : /* If signedness of arg0 and arg1 don't match,
832 : we can't necessarily find a type to compare them in. */
833 48934 : && (TYPE_UNSIGNED (TREE_TYPE (arg0))
834 4755 : == TYPE_UNSIGNED (TREE_TYPE (arg1))))
835 4311 : goto trunc1;
836 : break;
837 : }
838 :
839 716598 : case PLUS_EXPR:
840 716598 : case MINUS_EXPR:
841 716598 : case BIT_AND_EXPR:
842 716598 : case BIT_IOR_EXPR:
843 716598 : case BIT_XOR_EXPR:
844 716598 : trunc1:
845 716598 : {
846 716598 : tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
847 716598 : tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
848 :
849 : /* Do not try to narrow operands of pointer subtraction;
850 : that will interfere with other folding. */
851 716598 : if (ex_form == MINUS_EXPR
852 5918 : && CONVERT_EXPR_P (arg0)
853 138 : && CONVERT_EXPR_P (arg1)
854 55 : && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg0, 0)))
855 716618 : && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg1, 0))))
856 : break;
857 :
858 716578 : tree tem = do_narrow (loc, ex_form, type, arg0, arg1,
859 : expr, inprec, outprec, dofold);
860 716578 : if (tem)
861 : return tem;
862 : }
863 : break;
864 :
865 72278 : case NEGATE_EXPR:
866 : /* Using unsigned arithmetic for signed types may hide overflow
867 : bugs. */
868 72278 : if (!TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (expr, 0)))
869 72278 : && sanitize_flags_p (SANITIZE_SI_OVERFLOW))
870 : break;
871 : /* Fall through. */
872 170643 : case BIT_NOT_EXPR:
873 : /* This is not correct for ABS_EXPR,
874 : since we must test the sign before truncation. */
875 170643 : {
876 : /* Do the arithmetic in type TYPEX,
877 : then convert result to TYPE. */
878 170643 : tree typex = type;
879 :
880 : /* Can't do arithmetic in enumeral types
881 : so use an integer type that will hold the values. */
882 170643 : if (TREE_CODE (typex) == ENUMERAL_TYPE)
883 0 : typex
884 0 : = lang_hooks.types.type_for_size (TYPE_PRECISION (typex),
885 0 : TYPE_UNSIGNED (typex));
886 :
887 170643 : if (!TYPE_UNSIGNED (typex))
888 71384 : typex = unsigned_type_for (typex);
889 170643 : return convert (type,
890 170643 : fold_build1 (ex_form, typex,
891 : convert (typex,
892 170643 : TREE_OPERAND (expr, 0))));
893 : }
894 :
895 2570787 : CASE_CONVERT:
896 2570787 : {
897 2570787 : tree argtype = TREE_TYPE (TREE_OPERAND (expr, 0));
898 : /* Don't introduce a "can't convert between vector values
899 : of different size" error. */
900 2570787 : if (TREE_CODE (argtype) == VECTOR_TYPE
901 2570787 : && maybe_ne (GET_MODE_SIZE (TYPE_MODE (argtype)),
902 0 : GET_MODE_SIZE (TYPE_MODE (type))))
903 : break;
904 : }
905 : /* If truncating after truncating, might as well do all at once.
906 : If truncating after extending, we may get rid of wasted work. */
907 2570787 : return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type));
908 :
909 117620 : case COND_EXPR:
910 : /* It is sometimes worthwhile to push the narrowing down through
911 : the conditional and never loses. A COND_EXPR may have a throw
912 : as one operand, which then has void type. Just leave void
913 : operands as they are. */
914 117620 : return
915 117620 : fold_build3 (COND_EXPR, type, TREE_OPERAND (expr, 0),
916 : VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 1)))
917 : ? TREE_OPERAND (expr, 1)
918 : : convert (type, TREE_OPERAND (expr, 1)),
919 : VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 2)))
920 : ? TREE_OPERAND (expr, 2)
921 : : convert (type, TREE_OPERAND (expr, 2)));
922 :
923 : default:
924 : break;
925 : }
926 :
927 : /* When parsing long initializers, we might end up with a lot of casts.
928 : Shortcut this. */
929 26757603 : if (TREE_CODE (tree_strip_any_location_wrapper (expr)) == INTEGER_CST)
930 17987838 : return fold_convert (type, expr);
931 8769765 : return build1 (CONVERT_EXPR, type, expr);
932 :
933 452661 : case REAL_TYPE:
934 452661 : if (sanitize_flags_p (SANITIZE_FLOAT_CAST)
935 452661 : && current_function_decl != NULL_TREE)
936 : {
937 4978 : expr = save_expr (expr);
938 4978 : tree check = ubsan_instrument_float_cast (loc, type, expr);
939 4978 : expr = build1 (FIX_TRUNC_EXPR, type, expr);
940 4978 : if (check == NULL_TREE)
941 : return expr;
942 4969 : return maybe_fold_build2_loc (dofold, loc, COMPOUND_EXPR,
943 : TREE_TYPE (expr), check, expr);
944 : }
945 : else
946 447683 : return build1 (FIX_TRUNC_EXPR, type, expr);
947 :
948 0 : case FIXED_POINT_TYPE:
949 0 : return build1 (FIXED_CONVERT_EXPR, type, expr);
950 :
951 7222 : case COMPLEX_TYPE:
952 7222 : expr = maybe_fold_build1_loc (dofold, loc, REALPART_EXPR,
953 : TREE_TYPE (TREE_TYPE (expr)), expr);
954 7222 : return convert (type, expr);
955 :
956 35966 : case VECTOR_TYPE:
957 35966 : if (!tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (expr))))
958 : {
959 5 : error ("cannot convert a vector of type %qT"
960 : " to type %qT which has different size",
961 5 : TREE_TYPE (expr), type);
962 5 : return error_mark_node;
963 : }
964 35961 : return build1 (VIEW_CONVERT_EXPR, type, expr);
965 :
966 10 : default:
967 10 : error ("aggregate value used where an integer was expected");
968 10 : return error_mark_node;
969 : }
970 : }
971 :
972 : /* Convert EXPR to some integer (or enum) type TYPE.
973 :
974 : EXPR must be pointer, integer, discrete (enum, char, or bool), float,
975 : fixed-point or vector; in other cases error is called.
976 :
977 : The result of this is always supposed to be a newly created tree node
978 : not in use in any existing structure. */
979 :
980 : tree
981 32122691 : convert_to_integer (tree type, tree expr)
982 : {
983 32122691 : return convert_to_integer_1 (type, expr, true);
984 : }
985 :
986 : /* A wrapper around convert_to_complex_1 that only folds the
987 : expression if DOFOLD, or if it is CONSTANT_CLASS_OR_WRAPPER_P. */
988 :
989 : tree
990 233754556 : convert_to_integer_maybe_fold (tree type, tree expr, bool dofold)
991 : {
992 233754556 : tree result
993 233754556 : = convert_to_integer_1 (type, expr,
994 233754556 : dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
995 233754556 : return preserve_any_location_wrapper (result, expr);
996 : }
997 :
998 : /* Convert EXPR to the complex type TYPE in the usual ways. If FOLD_P is
999 : true, try to fold the expression. */
1000 :
1001 : static tree
1002 467243 : convert_to_complex_1 (tree type, tree expr, bool fold_p)
1003 : {
1004 467243 : location_t loc = EXPR_LOCATION (expr);
1005 467243 : tree subtype = TREE_TYPE (type);
1006 :
1007 467243 : switch (TREE_CODE (TREE_TYPE (expr)))
1008 : {
1009 149131 : case REAL_TYPE:
1010 149131 : case FIXED_POINT_TYPE:
1011 149131 : case INTEGER_TYPE:
1012 149131 : case ENUMERAL_TYPE:
1013 149131 : case BOOLEAN_TYPE:
1014 149131 : case BITINT_TYPE:
1015 149131 : {
1016 149131 : tree real = convert (subtype, expr);
1017 149131 : tree imag = convert (subtype, integer_zero_node);
1018 149131 : if (error_operand_p (real) || error_operand_p (imag))
1019 1 : return error_mark_node;
1020 149130 : return build2 (COMPLEX_EXPR, type, real, imag);
1021 : }
1022 :
1023 318103 : case COMPLEX_TYPE:
1024 318103 : {
1025 318103 : tree elt_type = TREE_TYPE (TREE_TYPE (expr));
1026 :
1027 318103 : if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1028 : return expr;
1029 280614 : else if (TREE_CODE (expr) == COMPOUND_EXPR)
1030 : {
1031 40 : tree t = convert_to_complex_1 (type, TREE_OPERAND (expr, 1),
1032 : fold_p);
1033 40 : if (t == TREE_OPERAND (expr, 1))
1034 : return expr;
1035 40 : return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR,
1036 80 : TREE_TYPE (t), TREE_OPERAND (expr, 0), t);
1037 : }
1038 280574 : else if (TREE_CODE (expr) == COMPLEX_EXPR)
1039 2371 : return maybe_fold_build2_loc (fold_p, loc, COMPLEX_EXPR, type,
1040 : convert (subtype,
1041 : TREE_OPERAND (expr, 0)),
1042 : convert (subtype,
1043 : TREE_OPERAND (expr, 1)));
1044 : else
1045 : {
1046 278203 : expr = save_expr (expr);
1047 278203 : tree realp = maybe_fold_build1_loc (fold_p, loc, REALPART_EXPR,
1048 : TREE_TYPE (TREE_TYPE (expr)),
1049 : expr);
1050 278203 : tree imagp = maybe_fold_build1_loc (fold_p, loc, IMAGPART_EXPR,
1051 : TREE_TYPE (TREE_TYPE (expr)),
1052 : expr);
1053 278203 : return maybe_fold_build2_loc (fold_p, loc, COMPLEX_EXPR, type,
1054 : convert (subtype, realp),
1055 : convert (subtype, imagp));
1056 : }
1057 : }
1058 :
1059 3 : case POINTER_TYPE:
1060 3 : case REFERENCE_TYPE:
1061 3 : error ("pointer value used where a complex was expected");
1062 3 : return error_mark_node;
1063 :
1064 6 : default:
1065 6 : error ("aggregate value used where a complex was expected");
1066 6 : return error_mark_node;
1067 : }
1068 : }
1069 :
1070 : /* A wrapper around convert_to_complex_1 that always folds the
1071 : expression. */
1072 :
1073 : tree
1074 136527 : convert_to_complex (tree type, tree expr)
1075 : {
1076 136527 : return convert_to_complex_1 (type, expr, true);
1077 : }
1078 :
1079 : /* A wrapper around convert_to_complex_1 that only folds the
1080 : expression if DOFOLD, or if it is CONSTANT_CLASS_OR_WRAPPER_P. */
1081 :
1082 : tree
1083 330676 : convert_to_complex_maybe_fold (tree type, tree expr, bool dofold)
1084 : {
1085 330676 : tree result
1086 330676 : = convert_to_complex_1 (type, expr,
1087 330676 : dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
1088 330676 : return preserve_any_location_wrapper (result, expr);
1089 : }
1090 :
1091 : /* Convert EXPR to the vector type TYPE in the usual ways. */
1092 :
1093 : tree
1094 102937047 : convert_to_vector (tree type, tree expr)
1095 : {
1096 102937047 : switch (TREE_CODE (TREE_TYPE (expr)))
1097 : {
1098 102937039 : case INTEGER_TYPE:
1099 102937039 : case VECTOR_TYPE:
1100 102937039 : if (!tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (expr))))
1101 : {
1102 4 : error ("cannot convert a value of type %qT"
1103 : " to vector type %qT which has different size",
1104 4 : TREE_TYPE (expr), type);
1105 4 : return error_mark_node;
1106 : }
1107 102937035 : return build1 (VIEW_CONVERT_EXPR, type, expr);
1108 :
1109 8 : default:
1110 8 : error ("cannot convert value to a vector");
1111 8 : return error_mark_node;
1112 : }
1113 : }
1114 :
1115 : /* Convert EXPR to some fixed-point type TYPE.
1116 :
1117 : EXPR must be fixed-point, float, integer, or enumeral;
1118 : in other cases error is called. */
1119 :
1120 : tree
1121 0 : convert_to_fixed (tree type, tree expr)
1122 : {
1123 0 : if (integer_zerop (expr))
1124 : {
1125 0 : tree fixed_zero_node = build_fixed (type, FCONST0 (TYPE_MODE (type)));
1126 0 : return fixed_zero_node;
1127 : }
1128 0 : else if (integer_onep (expr) && ALL_SCALAR_ACCUM_MODE_P (TYPE_MODE (type)))
1129 : {
1130 0 : tree fixed_one_node = build_fixed (type, FCONST1 (TYPE_MODE (type)));
1131 0 : return fixed_one_node;
1132 : }
1133 :
1134 0 : switch (TREE_CODE (TREE_TYPE (expr)))
1135 : {
1136 0 : case FIXED_POINT_TYPE:
1137 0 : case INTEGER_TYPE:
1138 0 : case ENUMERAL_TYPE:
1139 0 : case BOOLEAN_TYPE:
1140 0 : case REAL_TYPE:
1141 0 : return build1 (FIXED_CONVERT_EXPR, type, expr);
1142 :
1143 0 : case COMPLEX_TYPE:
1144 0 : return convert (type,
1145 0 : fold_build1 (REALPART_EXPR,
1146 0 : TREE_TYPE (TREE_TYPE (expr)), expr));
1147 :
1148 0 : default:
1149 0 : error ("aggregate value used where a fixed-point was expected");
1150 0 : return error_mark_node;
1151 : }
1152 : }
1153 :
1154 : #if CHECKING_P
1155 :
1156 : namespace selftest {
1157 :
1158 : /* Selftests for conversions. */
1159 :
1160 : static void
1161 16 : test_convert_to_integer_maybe_fold (tree orig_type, tree new_type)
1162 : {
1163 : /* Calling convert_to_integer_maybe_fold on an INTEGER_CST. */
1164 :
1165 16 : tree orig_cst = build_int_cst (orig_type, 42);
1166 :
1167 : /* Verify that convert_to_integer_maybe_fold on a constant returns a new
1168 : constant of the new type, unless the types are the same, in which
1169 : case verify it's a no-op. */
1170 16 : {
1171 16 : tree result = convert_to_integer_maybe_fold (new_type,
1172 : orig_cst, false);
1173 16 : if (orig_type != new_type)
1174 : {
1175 8 : ASSERT_EQ (TREE_TYPE (result), new_type);
1176 8 : ASSERT_EQ (TREE_CODE (result), INTEGER_CST);
1177 : }
1178 : else
1179 8 : ASSERT_EQ (result, orig_cst);
1180 : }
1181 :
1182 : /* Calling convert_to_integer_maybe_fold on a location wrapper around
1183 : an INTEGER_CST.
1184 :
1185 : Verify that convert_to_integer_maybe_fold on a location wrapper
1186 : around a constant returns a new location wrapper around an equivalent
1187 : constant, both of the new type, unless the types are the same,
1188 : in which case the original wrapper should be returned. */
1189 16 : {
1190 16 : const location_t loc = BUILTINS_LOCATION;
1191 16 : tree wrapped_orig_cst = maybe_wrap_with_location (orig_cst, loc);
1192 16 : tree result
1193 16 : = convert_to_integer_maybe_fold (new_type, wrapped_orig_cst, false);
1194 16 : ASSERT_EQ (TREE_TYPE (result), new_type);
1195 16 : ASSERT_EQ (EXPR_LOCATION (result), loc);
1196 16 : ASSERT_TRUE (location_wrapper_p (result));
1197 16 : ASSERT_EQ (TREE_TYPE (TREE_OPERAND (result, 0)), new_type);
1198 16 : ASSERT_EQ (TREE_CODE (TREE_OPERAND (result, 0)), INTEGER_CST);
1199 :
1200 16 : if (orig_type == new_type)
1201 8 : ASSERT_EQ (result, wrapped_orig_cst);
1202 : }
1203 16 : }
1204 :
1205 : /* Verify that convert_to_integer_maybe_fold preserves locations. */
1206 :
1207 : static void
1208 4 : test_convert_to_integer_maybe_fold ()
1209 : {
1210 : /* char -> long. */
1211 4 : test_convert_to_integer_maybe_fold (char_type_node, long_integer_type_node);
1212 :
1213 : /* char -> char. */
1214 4 : test_convert_to_integer_maybe_fold (char_type_node, char_type_node);
1215 :
1216 : /* long -> char. */
1217 4 : test_convert_to_integer_maybe_fold (char_type_node, long_integer_type_node);
1218 :
1219 : /* long -> long. */
1220 4 : test_convert_to_integer_maybe_fold (long_integer_type_node,
1221 : long_integer_type_node);
1222 4 : }
1223 :
1224 : /* Run all of the selftests within this file. */
1225 :
1226 : void
1227 4 : convert_cc_tests ()
1228 : {
1229 4 : test_convert_to_integer_maybe_fold ();
1230 4 : }
1231 :
1232 : } // namespace selftest
1233 :
1234 : #endif /* CHECKING_P */
|