Branch data Line data Source code
1 : : /* Utility routines for data type conversion for GCC.
2 : : Copyright (C) 1987-2024 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 : 6949520 : convert_to_pointer_1 (tree type, tree expr, bool fold_p)
55 : : {
56 : 6949520 : location_t loc = EXPR_LOCATION (expr);
57 : 6949520 : if (TREE_TYPE (expr) == type)
58 : : return expr;
59 : :
60 : 6949520 : switch (TREE_CODE (TREE_TYPE (expr)))
61 : : {
62 : 6400770 : case POINTER_TYPE:
63 : 6400770 : case REFERENCE_TYPE:
64 : 6400770 : {
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 : 6400770 : addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (type));
68 : 6400770 : addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
69 : :
70 : 6400770 : if (to_as == from_as)
71 : 6400770 : 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 : 548737 : case INTEGER_TYPE:
78 : 548737 : case ENUMERAL_TYPE:
79 : 548737 : case BOOLEAN_TYPE:
80 : 548737 : case BITINT_TYPE:
81 : 548737 : {
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 : 548737 : unsigned int pprec = TYPE_PRECISION (type);
87 : 548737 : unsigned int eprec = TYPE_PRECISION (TREE_TYPE (expr));
88 : :
89 : 548737 : if (eprec != pprec)
90 : 490049 : expr
91 : 490049 : = maybe_fold_build1_loc (fold_p, loc, NOP_EXPR,
92 : : lang_hooks.types.type_for_size (pprec, 0),
93 : : expr);
94 : : }
95 : 548737 : return maybe_fold_build1_loc (fold_p, loc, CONVERT_EXPR, type, expr);
96 : :
97 : 13 : default:
98 : 13 : error ("cannot convert to a pointer type");
99 : 13 : 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 : 273252163 : preserve_any_location_wrapper (tree result, tree orig_expr)
110 : : {
111 : 273252163 : if (CONSTANT_CLASS_P (result) && location_wrapper_p (orig_expr))
112 : : {
113 : 28378078 : if (result == TREE_OPERAND (orig_expr, 0))
114 : : return orig_expr;
115 : : else
116 : 14189935 : 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 : 6949520 : convert_to_pointer (tree type, tree expr)
127 : : {
128 : 6949520 : 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 : 20746870 : convert_to_real_1 (tree type, tree expr, bool fold_p)
151 : : {
152 : 20746870 : enum built_in_function fcode = builtin_mathfn_code (expr);
153 : 20746870 : tree itype = TREE_TYPE (expr);
154 : 20746870 : location_t loc = EXPR_LOCATION (expr);
155 : :
156 : 20746870 : 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 : 20746419 : if (optimize
169 : 20746419 : && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
170 : 18868122 : || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
171 : : {
172 : 11586113 : switch (fcode)
173 : : {
174 : : #define CASE_MATHFN(FN) case BUILT_IN_##FN: case BUILT_IN_##FN##L:
175 : 16469 : CASE_MATHFN (COSH)
176 : 16469 : CASE_MATHFN (EXP)
177 : 16469 : CASE_MATHFN (EXP10)
178 : 16469 : CASE_MATHFN (EXP2)
179 : 16469 : CASE_MATHFN (EXPM1)
180 : 16469 : CASE_MATHFN (GAMMA)
181 : 16469 : CASE_MATHFN (J0)
182 : 16469 : CASE_MATHFN (J1)
183 : 16469 : CASE_MATHFN (LGAMMA)
184 : 16469 : CASE_MATHFN (POW10)
185 : 16469 : CASE_MATHFN (SINH)
186 : 16469 : CASE_MATHFN (TGAMMA)
187 : 16469 : CASE_MATHFN (Y0)
188 : 16469 : 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 : 16469 : if (flag_errno_math)
193 : : break;
194 : 40529 : gcc_fallthrough ();
195 : 40529 : CASE_MATHFN (ACOS)
196 : 40529 : CASE_MATHFN (ACOSH)
197 : 40529 : CASE_MATHFN (ASIN)
198 : 40529 : CASE_MATHFN (ASINH)
199 : 40529 : CASE_MATHFN (ATAN)
200 : 40529 : CASE_MATHFN (ATANH)
201 : 40529 : CASE_MATHFN (CBRT)
202 : 40529 : CASE_MATHFN (COS)
203 : 40529 : CASE_MATHFN (ERF)
204 : 40529 : CASE_MATHFN (ERFC)
205 : 40529 : CASE_MATHFN (LOG)
206 : 40529 : CASE_MATHFN (LOG10)
207 : 40529 : CASE_MATHFN (LOG2)
208 : 40529 : CASE_MATHFN (LOG1P)
209 : 40529 : CASE_MATHFN (SIN)
210 : 40529 : CASE_MATHFN (TAN)
211 : 40529 : CASE_MATHFN (TANH)
212 : : /* The above functions are not safe to do this conversion. */
213 : 40529 : if (!flag_unsafe_math_optimizations)
214 : : break;
215 : 8736 : gcc_fallthrough ();
216 : 8736 : CASE_MATHFN (SQRT)
217 : 8736 : CASE_MATHFN (FABS)
218 : 8736 : CASE_MATHFN (LOGB)
219 : : #undef CASE_MATHFN
220 : 8736 : if (call_expr_nargs (expr) != 1
221 : 17472 : || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (expr, 0))))
222 : : break;
223 : 8636 : {
224 : 8636 : tree arg0 = strip_float_extensions (CALL_EXPR_ARG (expr, 0));
225 : 8636 : 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 : 8636 : 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 : 8636 : if ((fcode == BUILT_IN_SQRT || fcode == BUILT_IN_SQRTL)
247 : 2383 : && !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 : 2321 : if (TYPE_MODE (type) != TYPE_MODE (newtype))
255 : : break;
256 : :
257 : 2320 : int p1 = REAL_MODE_FORMAT (TYPE_MODE (itype))->p;
258 : 2320 : int p2 = REAL_MODE_FORMAT (TYPE_MODE (newtype))->p;
259 : 2320 : if (p1 < p2 * 2 + 2)
260 : : break;
261 : : }
262 : :
263 : : /* Be careful about integer to fp conversions.
264 : : These may overflow still. */
265 : 6326 : if (FLOAT_TYPE_P (TREE_TYPE (arg0))
266 : 6326 : && TYPE_PRECISION (newtype) < TYPE_PRECISION (itype)
267 : 7719 : && (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 : 20745026 : if (itype != type && FLOAT_TYPE_P (type))
287 : 20720034 : 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 : 67083 : case ABS_EXPR:
292 : 67083 : case NEGATE_EXPR:
293 : 67083 : if (!flag_rounding_math
294 : 67082 : && FLOAT_TYPE_P (itype)
295 : 95010 : && element_precision (type) < element_precision (itype))
296 : : {
297 : 3711 : tree arg = convert_to_real_1 (type, TREE_OPERAND (expr, 0),
298 : : fold_p);
299 : 3711 : return build1 (TREE_CODE (expr), type, arg);
300 : : }
301 : : break;
302 : : default:
303 : : break;
304 : : }
305 : :
306 : 20741315 : switch (TREE_CODE (TREE_TYPE (expr)))
307 : : {
308 : 3773298 : 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 : 3773298 : return build1_loc (loc,
312 : 3773298 : (flag_float_store
313 : 3773189 : || DECIMAL_FLOAT_TYPE_P (type)
314 : 3755667 : || DECIMAL_FLOAT_TYPE_P (itype))
315 : 3773298 : ? CONVERT_EXPR : NOP_EXPR, type, expr);
316 : :
317 : 16965911 : case INTEGER_TYPE:
318 : 16965911 : case ENUMERAL_TYPE:
319 : 16965911 : case BOOLEAN_TYPE:
320 : 16965911 : case BITINT_TYPE:
321 : 16965911 : return build1 (FLOAT_EXPR, type, expr);
322 : :
323 : 0 : case FIXED_POINT_TYPE:
324 : 0 : return build1 (FIXED_CONVERT_EXPR, type, expr);
325 : :
326 : 2080 : case COMPLEX_TYPE:
327 : 4160 : return convert (type,
328 : 2080 : maybe_fold_build1_loc (fold_p, loc, REALPART_EXPR,
329 : : TREE_TYPE (TREE_TYPE (expr)),
330 : 2080 : expr));
331 : :
332 : 3 : case POINTER_TYPE:
333 : 3 : case REFERENCE_TYPE:
334 : 3 : error ("pointer value used where a floating-point was expected");
335 : 3 : 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 : 1057733 : convert_to_real (tree type, tree expr)
352 : : {
353 : 1057733 : 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 : 19683582 : convert_to_real_maybe_fold (tree type, tree expr, bool dofold)
361 : : {
362 : 19683582 : tree result
363 : 19683582 : = convert_to_real_1 (type, expr,
364 : 19683582 : dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
365 : 19683582 : 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 : 437066 : 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 : 437066 : tree typex = type;
379 : :
380 : : /* Can't do arithmetic in enumeral types
381 : : so use an integer type that will hold the values. */
382 : 437066 : 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 : 437066 : if ((ex_form == PLUS_EXPR || ex_form == MINUS_EXPR)
389 : 263182 : && !TYPE_UNSIGNED (typex)
390 : 666331 : && 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 : 436953 : if (ex_form == MULT_EXPR
397 : 2435 : && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr))
398 : 439294 : && 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 : 436914 : 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 : 436914 : if (TYPE_UNSIGNED (TREE_TYPE (expr))
418 : 89821 : || (TYPE_UNSIGNED (TREE_TYPE (arg0))
419 : 20136 : && (TYPE_UNSIGNED (TREE_TYPE (arg1))
420 : : || ex_form == LSHIFT_EXPR
421 : 14745 : || ex_form == RSHIFT_EXPR
422 : : || ex_form == LROTATE_EXPR
423 : 14172 : || ex_form == RROTATE_EXPR))
424 : 83857 : || 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 : 520401 : || ((!(INTEGRAL_TYPE_P (TREE_TYPE (arg0))
432 : 83487 : && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0)))
433 : 15125 : || !(INTEGRAL_TYPE_P (TREE_TYPE (arg1))
434 : 15125 : && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1))))
435 : 82517 : && ((TYPE_PRECISION (TREE_TYPE (arg0)) * 2u
436 : : > outprec)
437 : 2809 : || (TYPE_PRECISION (TREE_TYPE (arg1)) * 2u
438 : : > outprec))
439 : 82425 : && (ex_form == PLUS_EXPR
440 : : || ex_form == MINUS_EXPR
441 : : || ex_form == MULT_EXPR)))
442 : : {
443 : 392116 : if (!TYPE_UNSIGNED (typex))
444 : 250519 : typex = unsigned_type_for (typex);
445 : : }
446 : : else
447 : : {
448 : 44798 : if (TYPE_UNSIGNED (typex))
449 : 9896 : 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 : 436914 : expr = maybe_fold_build2_loc (dofold, loc, ex_form, typex,
454 : : convert (typex, arg0),
455 : : convert (typex, arg1));
456 : 436914 : 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 : 175984173 : convert_to_integer_1 (tree type, tree expr, bool dofold)
474 : : {
475 : 175984173 : enum tree_code ex_form = TREE_CODE (expr);
476 : 175984173 : tree intype = TREE_TYPE (expr);
477 : 175984173 : unsigned int inprec = element_precision (intype);
478 : 175984173 : unsigned int outprec = element_precision (type);
479 : 175984173 : 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 : 175984173 : if (!COMPLETE_TYPE_P (type))
484 : : {
485 : 4 : error ("conversion to incomplete type");
486 : 4 : return error_mark_node;
487 : : }
488 : :
489 : 175984169 : if (ex_form == COMPOUND_EXPR)
490 : : {
491 : 44341 : tree t = convert_to_integer_1 (type, TREE_OPERAND (expr, 1), dofold);
492 : 44341 : if (t == TREE_OPERAND (expr, 1))
493 : : return expr;
494 : 41468 : return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR, TREE_TYPE (t),
495 : 82936 : 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 : 175939828 : if (optimize
504 : 175939828 : && (flag_unsafe_math_optimizations
505 : 165288594 : || (long_integer_type_node
506 : 165288594 : && outprec >= TYPE_PRECISION (long_integer_type_node))))
507 : : {
508 : 66859811 : tree s_expr = strip_float_extensions (expr);
509 : 66859811 : tree s_intype = TREE_TYPE (s_expr);
510 : 66859811 : const enum built_in_function fcode = builtin_mathfn_code (s_expr);
511 : 66859811 : tree fn = 0;
512 : :
513 : 66859811 : switch (fcode)
514 : : {
515 : 38691 : CASE_FLT_FN (BUILT_IN_CEIL):
516 : 38691 : CASE_FLT_FN_FLOATN_NX (BUILT_IN_CEIL):
517 : : /* Only convert in ISO C99 mode. */
518 : 38691 : if (!targetm.libc_has_function (function_c99_misc, intype))
519 : : break;
520 : 38691 : if (outprec < TYPE_PRECISION (integer_type_node)
521 : 38691 : || (outprec == TYPE_PRECISION (integer_type_node)
522 : 69 : && !TYPE_UNSIGNED (type)))
523 : 20 : fn = mathfn_built_in (s_intype, BUILT_IN_ICEIL);
524 : 38671 : else if (outprec == TYPE_PRECISION (long_integer_type_node)
525 : 38671 : && !TYPE_UNSIGNED (type))
526 : 81 : fn = mathfn_built_in (s_intype, BUILT_IN_LCEIL);
527 : 38590 : else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
528 : 38590 : && !TYPE_UNSIGNED (type))
529 : 0 : fn = mathfn_built_in (s_intype, BUILT_IN_LLCEIL);
530 : : break;
531 : :
532 : 38296 : CASE_FLT_FN (BUILT_IN_FLOOR):
533 : 38296 : CASE_FLT_FN_FLOATN_NX (BUILT_IN_FLOOR):
534 : : /* Only convert in ISO C99 mode. */
535 : 38296 : if (!targetm.libc_has_function (function_c99_misc, intype))
536 : : break;
537 : 38296 : if (outprec < TYPE_PRECISION (integer_type_node)
538 : 38296 : || (outprec == TYPE_PRECISION (integer_type_node)
539 : 63 : && !TYPE_UNSIGNED (type)))
540 : 21 : fn = mathfn_built_in (s_intype, BUILT_IN_IFLOOR);
541 : 38275 : else if (outprec == TYPE_PRECISION (long_integer_type_node)
542 : 38275 : && !TYPE_UNSIGNED (type))
543 : 82 : fn = mathfn_built_in (s_intype, BUILT_IN_LFLOOR);
544 : 38193 : else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
545 : 38193 : && !TYPE_UNSIGNED (type))
546 : 0 : fn = mathfn_built_in (s_intype, BUILT_IN_LLFLOOR);
547 : : break;
548 : :
549 : 105 : CASE_FLT_FN (BUILT_IN_ROUND):
550 : 105 : CASE_FLT_FN_FLOATN_NX (BUILT_IN_ROUND):
551 : : /* Only convert in ISO C99 mode and with -fno-math-errno. */
552 : 105 : if (!targetm.libc_has_function (function_c99_misc, intype)
553 : 105 : || 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 : 175939354 : if (optimize
615 : 166508888 : && flag_unsafe_math_optimizations
616 : 1220297 : && !flag_trapping_math && !flag_errno_math && flag_finite_math_only
617 : 1220143 : && integer_type_node
618 : 177159497 : && (outprec > TYPE_PRECISION (integer_type_node)
619 : 916972 : || (outprec == TYPE_PRECISION (integer_type_node)
620 : 705970 : && !TYPE_UNSIGNED (type))))
621 : : {
622 : 864167 : tree s_expr = strip_float_extensions (expr);
623 : 864167 : tree s_intype = TREE_TYPE (s_expr);
624 : 864167 : const enum built_in_function fcode = builtin_mathfn_code (s_expr);
625 : 864167 : tree fn = 0;
626 : :
627 : 864167 : 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 : 175939351 : switch (TREE_CODE (intype))
647 : : {
648 : 775755 : case POINTER_TYPE:
649 : 775755 : case REFERENCE_TYPE:
650 : 775755 : if (integer_zerop (expr)
651 : 775755 : && !TREE_OVERFLOW (tree_strip_any_location_wrapper (expr)))
652 : 18824 : 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 : 756931 : if (!dofold)
659 : 138427 : return build1 (CONVERT_EXPR, type, expr);
660 : 618504 : expr = fold_build1 (CONVERT_EXPR,
661 : : lang_hooks.types.type_for_size
662 : : (TYPE_PRECISION (intype), 0),
663 : : expr);
664 : 618504 : return fold_convert (type, expr);
665 : :
666 : 174658820 : case INTEGER_TYPE:
667 : 174658820 : case ENUMERAL_TYPE:
668 : 174658820 : case BOOLEAN_TYPE:
669 : 174658820 : case OFFSET_TYPE:
670 : 174658820 : 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 : 174658820 : if (TREE_CODE_CLASS (ex_form) == tcc_comparison)
675 : : {
676 : 2111505 : expr = copy_node (expr);
677 : 2111505 : TREE_TYPE (expr) = type;
678 : 2111505 : 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 : 172547315 : else if (outprec >= inprec)
686 : : {
687 : 150190045 : 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 : 150190045 : if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (TREE_TYPE (expr))
699 : 150190045 : && !type_has_mode_precision_p (TREE_TYPE (expr)))
700 : : code = CONVERT_EXPR;
701 : : else
702 : : code = NOP_EXPR;
703 : :
704 : 150190045 : 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 : 22357270 : else if (TREE_CODE (type) == ENUMERAL_TYPE
712 : 22357270 : || (TREE_CODE (type) != BITINT_TYPE
713 : 22251660 : && maybe_ne (outprec,
714 : 22251660 : GET_MODE_PRECISION (TYPE_MODE (type)))))
715 : : {
716 : 849196 : expr
717 : 849196 : = convert_to_integer_1 (lang_hooks.types.type_for_mode
718 : 849196 : (TYPE_MODE (type), TYPE_UNSIGNED (type)),
719 : : expr, dofold);
720 : 849196 : 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 : 21508074 : if (dofold)
744 : 17857841 : switch (ex_form)
745 : : {
746 : 65937 : case RSHIFT_EXPR:
747 : : /* We can pass truncation down through right shifting
748 : : when the shift count is a nonpositive constant. */
749 : 65937 : if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
750 : 65937 : && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) <= 0)
751 : 31 : goto trunc1;
752 : : break;
753 : :
754 : 11284 : 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 : 11284 : if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
759 : 2766 : && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) >= 0
760 : 2766 : && TYPE_UNSIGNED (type)
761 : 12672 : && 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 : 1388 : if (wi::to_widest (TREE_OPERAND (expr, 1))
766 : 2776 : < TYPE_PRECISION (type))
767 : : /* In this case, shifting is like multiplication. */
768 : 1365 : 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 : 16250 : case TRUNC_DIV_EXPR:
790 : 16250 : {
791 : 16250 : tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), NULL_TREE);
792 : 16250 : 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 : 16250 : if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
797 : 12232 : && 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 : 494 : && (TYPE_UNSIGNED (TREE_TYPE (arg0))
801 : 494 : == TYPE_UNSIGNED (TREE_TYPE (arg1)))
802 : : /* Do not change the sign of the division. */
803 : 328 : && (TYPE_UNSIGNED (TREE_TYPE (expr))
804 : 328 : == TYPE_UNSIGNED (TREE_TYPE (arg0)))
805 : : /* Either require unsigned division or a division by
806 : : a constant that is not -1. */
807 : 16537 : && (TYPE_UNSIGNED (TREE_TYPE (arg0))
808 : 265 : || (TREE_CODE (arg1) == INTEGER_CST
809 : 160 : && !integer_all_onesp (arg1))))
810 : : {
811 : 182 : tree tem = do_narrow (loc, ex_form, type, arg0, arg1,
812 : : expr, inprec, outprec, dofold);
813 : 182 : if (tem)
814 : : return tem;
815 : : }
816 : : break;
817 : : }
818 : :
819 : 26683 : case MAX_EXPR:
820 : 26683 : case MIN_EXPR:
821 : 26683 : case MULT_EXPR:
822 : 26683 : {
823 : 26683 : tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
824 : 26683 : 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 : 26683 : if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
830 : 8438 : && 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 : 29954 : && (TYPE_UNSIGNED (TREE_TYPE (arg0))
834 : 3271 : == TYPE_UNSIGNED (TREE_TYPE (arg1))))
835 : 2842 : goto trunc1;
836 : : break;
837 : : }
838 : :
839 : 436904 : case PLUS_EXPR:
840 : 436904 : case MINUS_EXPR:
841 : 436904 : case BIT_AND_EXPR:
842 : 436904 : case BIT_IOR_EXPR:
843 : 436904 : case BIT_XOR_EXPR:
844 : 436904 : trunc1:
845 : 436904 : {
846 : 436904 : tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
847 : 436904 : 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 : 436904 : if (ex_form == MINUS_EXPR
852 : 4650 : && CONVERT_EXPR_P (arg0)
853 : 126 : && CONVERT_EXPR_P (arg1)
854 : 45 : && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg0, 0)))
855 : 436924 : && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg1, 0))))
856 : : break;
857 : :
858 : 436884 : tree tem = do_narrow (loc, ex_form, type, arg0, arg1,
859 : : expr, inprec, outprec, dofold);
860 : 436884 : if (tem)
861 : : return tem;
862 : : }
863 : : break;
864 : :
865 : 16552 : case NEGATE_EXPR:
866 : : /* Using unsigned arithmetic for signed types may hide overflow
867 : : bugs. */
868 : 16552 : if (!TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (expr, 0)))
869 : 16552 : && sanitize_flags_p (SANITIZE_SI_OVERFLOW))
870 : : break;
871 : : /* Fall through. */
872 : 91059 : case BIT_NOT_EXPR:
873 : : /* This is not correct for ABS_EXPR,
874 : : since we must test the sign before truncation. */
875 : 91059 : {
876 : : /* Do the arithmetic in type TYPEX,
877 : : then convert result to TYPE. */
878 : 91059 : tree typex = type;
879 : :
880 : : /* Can't do arithmetic in enumeral types
881 : : so use an integer type that will hold the values. */
882 : 91059 : 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 : 91059 : if (!TYPE_UNSIGNED (typex))
888 : 11691 : typex = unsigned_type_for (typex);
889 : 91059 : return convert (type,
890 : 91059 : fold_build1 (ex_form, typex,
891 : : convert (typex,
892 : 91059 : TREE_OPERAND (expr, 0))));
893 : : }
894 : :
895 : 1707945 : CASE_CONVERT:
896 : 1707945 : {
897 : 1707945 : 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 : 1707945 : if (TREE_CODE (argtype) == VECTOR_TYPE
901 : 1707945 : && 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 : 1707945 : return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type));
908 : :
909 : 74428 : 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 : 74428 : return
915 : 74428 : 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 : 19197705 : if (TREE_CODE (tree_strip_any_location_wrapper (expr)) == INTEGER_CST)
930 : 13740509 : return fold_convert (type, expr);
931 : 5457196 : return build1 (CONVERT_EXPR, type, expr);
932 : :
933 : 462354 : case REAL_TYPE:
934 : 462354 : if (sanitize_flags_p (SANITIZE_FLOAT_CAST)
935 : 462354 : && 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 : 457376 : 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 : 7240 : case COMPLEX_TYPE:
952 : 7240 : expr = maybe_fold_build1_loc (dofold, loc, REALPART_EXPR,
953 : : TREE_TYPE (TREE_TYPE (expr)), expr);
954 : 7240 : return convert (type, expr);
955 : :
956 : 35172 : case VECTOR_TYPE:
957 : 35172 : 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 : 35167 : 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 : 55336351 : convert_to_integer (tree type, tree expr)
982 : : {
983 : 55336351 : 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 : 119753808 : convert_to_integer_maybe_fold (tree type, tree expr, bool dofold)
991 : : {
992 : 119753808 : tree result
993 : 119753808 : = convert_to_integer_1 (type, expr,
994 : 119753808 : dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
995 : 119753808 : 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 : 583167 : convert_to_complex_1 (tree type, tree expr, bool fold_p)
1003 : : {
1004 : 583167 : location_t loc = EXPR_LOCATION (expr);
1005 : 583167 : tree subtype = TREE_TYPE (type);
1006 : :
1007 : 583167 : switch (TREE_CODE (TREE_TYPE (expr)))
1008 : : {
1009 : 151275 : case REAL_TYPE:
1010 : 151275 : case FIXED_POINT_TYPE:
1011 : 151275 : case INTEGER_TYPE:
1012 : 151275 : case ENUMERAL_TYPE:
1013 : 151275 : case BOOLEAN_TYPE:
1014 : 151275 : case BITINT_TYPE:
1015 : 151275 : {
1016 : 151275 : tree real = convert (subtype, expr);
1017 : 151275 : tree imag = convert (subtype, integer_zero_node);
1018 : 151275 : if (error_operand_p (real) || error_operand_p (imag))
1019 : 1 : return error_mark_node;
1020 : 151274 : return build2 (COMPLEX_EXPR, type, real, imag);
1021 : : }
1022 : :
1023 : 431883 : case COMPLEX_TYPE:
1024 : 431883 : {
1025 : 431883 : tree elt_type = TREE_TYPE (TREE_TYPE (expr));
1026 : :
1027 : 431883 : if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1028 : : return expr;
1029 : 396893 : 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 : 396853 : else if (TREE_CODE (expr) == COMPLEX_EXPR)
1039 : 2381 : 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 : 394472 : expr = save_expr (expr);
1047 : 394472 : tree realp = maybe_fold_build1_loc (fold_p, loc, REALPART_EXPR,
1048 : : TREE_TYPE (TREE_TYPE (expr)),
1049 : : expr);
1050 : 394472 : tree imagp = maybe_fold_build1_loc (fold_p, loc, IMAGPART_EXPR,
1051 : : TREE_TYPE (TREE_TYPE (expr)),
1052 : : expr);
1053 : 394472 : 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 : 134075 : convert_to_complex (tree type, tree expr)
1075 : : {
1076 : 134075 : 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 : 449052 : convert_to_complex_maybe_fold (tree type, tree expr, bool dofold)
1084 : : {
1085 : 449052 : tree result
1086 : 449052 : = convert_to_complex_1 (type, expr,
1087 : 449052 : dofold || CONSTANT_CLASS_OR_WRAPPER_P (expr));
1088 : 449052 : 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 : 105381115 : convert_to_vector (tree type, tree expr)
1095 : : {
1096 : 105381115 : switch (TREE_CODE (TREE_TYPE (expr)))
1097 : : {
1098 : 105381107 : case INTEGER_TYPE:
1099 : 105381107 : case VECTOR_TYPE:
1100 : 105381107 : 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 : 105381103 : 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 */
|