Line data Source code
1 : /* Support for fully folding sub-trees of an expression for C compiler.
2 : Copyright (C) 1992-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 : #include "config.h"
21 : #include "system.h"
22 : #include "coretypes.h"
23 : #include "target.h"
24 : #include "function.h"
25 : #include "bitmap.h"
26 : #include "c-tree.h"
27 : #include "intl.h"
28 : #include "gimplify.h"
29 :
30 : static tree c_fully_fold_internal (tree expr, bool, bool *, bool *, bool,
31 : bool);
32 :
33 : /* If DISABLE is true, stop issuing warnings. This is used when
34 : parsing code that we know will not be executed. This function may
35 : be called multiple times, and works as a stack. */
36 :
37 : static void
38 970013 : c_disable_warnings (bool disable)
39 : {
40 0 : if (disable)
41 : {
42 70523 : ++c_inhibit_evaluation_warnings;
43 : }
44 0 : }
45 :
46 : /* If ENABLE is true, re-enable issuing warnings. */
47 :
48 : static void
49 970013 : c_enable_warnings (bool enable)
50 : {
51 0 : if (enable)
52 : {
53 70523 : --c_inhibit_evaluation_warnings;
54 : }
55 0 : }
56 :
57 : /* Try to fold ARRAY_REF ary[index] if possible and not handled by
58 : normal fold, return NULL_TREE otherwise. */
59 :
60 : static tree
61 812 : c_fold_array_ref (tree type, tree ary, tree index)
62 : {
63 812 : if (TREE_CODE (ary) != STRING_CST
64 792 : || TREE_CODE (index) != INTEGER_CST
65 792 : || TREE_OVERFLOW (index)
66 791 : || TREE_CODE (TREE_TYPE (ary)) != ARRAY_TYPE
67 1603 : || !tree_fits_uhwi_p (index))
68 : return NULL_TREE;
69 :
70 790 : tree elem_type = TREE_TYPE (TREE_TYPE (ary));
71 790 : unsigned elem_nchars = (TYPE_PRECISION (elem_type)
72 790 : / TYPE_PRECISION (char_type_node));
73 790 : unsigned len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
74 790 : tree nelts_minus_one = array_type_nelts_minus_one (TREE_TYPE (ary));
75 790 : bool dummy1 = true, dummy2 = true;
76 790 : nelts_minus_one = c_fully_fold_internal (nelts_minus_one, true, &dummy1,
77 : &dummy2, false, false);
78 790 : unsigned HOST_WIDE_INT i = tree_to_uhwi (index);
79 790 : if (!tree_int_cst_le (index, nelts_minus_one)
80 789 : || i >= len
81 1579 : || i + elem_nchars > len)
82 : return NULL_TREE;
83 :
84 789 : if (elem_nchars == 1)
85 789 : return build_int_cst (type, TREE_STRING_POINTER (ary)[i]);
86 :
87 0 : const unsigned char *ptr
88 0 : = ((const unsigned char *)TREE_STRING_POINTER (ary) + i * elem_nchars);
89 0 : return native_interpret_expr (type, ptr, elem_nchars);
90 : }
91 :
92 : /* Fully fold EXPR, an expression that was not folded (beyond integer
93 : constant expressions and null pointer constants) when being built
94 : up. If IN_INIT, this is in a static initializer and certain
95 : changes are made to the folding done. Clear *MAYBE_CONST if
96 : MAYBE_CONST is not NULL and EXPR is definitely not a constant
97 : expression because it contains an evaluated operator (in C99) or an
98 : operator outside of sizeof returning an integer constant (in C90)
99 : not permitted in constant expressions, or because it contains an
100 : evaluated arithmetic overflow. (*MAYBE_CONST should typically be
101 : set to true by callers before calling this function.) Return the
102 : folded expression. Function arguments have already been folded
103 : before calling this function, as have the contents of SAVE_EXPR,
104 : TARGET_EXPR, BIND_EXPR, VA_ARG_EXPR, OBJ_TYPE_REF and
105 : C_MAYBE_CONST_EXPR. LVAL is true if it should be treated as an
106 : lvalue. */
107 :
108 : tree
109 270052638 : c_fully_fold (tree expr, bool in_init, bool *maybe_const, bool lval)
110 : {
111 270052638 : tree ret;
112 270052638 : tree eptype = NULL_TREE;
113 270052638 : bool dummy = true;
114 270052638 : bool maybe_const_itself = true;
115 270052638 : location_t loc = EXPR_LOCATION (expr);
116 :
117 270052638 : if (!maybe_const)
118 234499561 : maybe_const = &dummy;
119 270052638 : if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR)
120 : {
121 744 : eptype = TREE_TYPE (expr);
122 744 : expr = TREE_OPERAND (expr, 0);
123 : }
124 270052638 : ret = c_fully_fold_internal (expr, in_init, maybe_const,
125 : &maybe_const_itself, false, lval);
126 270052638 : if (eptype)
127 744 : ret = fold_convert_loc (loc, eptype, ret);
128 270052638 : *maybe_const &= maybe_const_itself;
129 270052638 : return ret;
130 : }
131 :
132 : /* Internal helper for c_fully_fold. EXPR and IN_INIT are as for
133 : c_fully_fold. *MAYBE_CONST_OPERANDS is cleared because of operands
134 : not permitted, while *MAYBE_CONST_ITSELF is cleared because of
135 : arithmetic overflow (for C90, *MAYBE_CONST_OPERANDS is carried from
136 : both evaluated and unevaluated subexpressions while
137 : *MAYBE_CONST_ITSELF is carried from only evaluated
138 : subexpressions). FOR_INT_CONST indicates if EXPR is an expression
139 : with integer constant operands, and if any of the operands doesn't
140 : get folded to an integer constant, don't fold the expression itself.
141 : LVAL indicates folding of lvalue, where we can't replace it with
142 : an rvalue. */
143 :
144 : static tree
145 485676916 : c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
146 : bool *maybe_const_itself, bool for_int_const, bool lval)
147 : {
148 485676916 : tree ret = expr;
149 485676916 : enum tree_code code = TREE_CODE (expr);
150 485676916 : enum tree_code_class kind = TREE_CODE_CLASS (code);
151 485676916 : location_t loc = EXPR_LOCATION (expr);
152 485676916 : tree op0, op1, op2, op3;
153 485676916 : tree orig_op0, orig_op1, orig_op2;
154 485676916 : bool op0_const = true, op1_const = true, op2_const = true;
155 485676916 : bool op0_const_self = true, op1_const_self = true, op2_const_self = true;
156 485676916 : bool nowarning = warning_suppressed_p (expr, OPT_Woverflow);
157 485676916 : bool unused_p;
158 485676916 : bool op0_lval = false;
159 485676916 : source_range old_range;
160 :
161 : /* Constants, declarations, statements, errors, and anything else not
162 : counted as an expression cannot usefully be folded further at this
163 : point. */
164 485676916 : if (!IS_EXPR_CODE_CLASS (kind) || kind == tcc_statement)
165 : {
166 : /* Except for variables which we can optimize to its initializer. */
167 228961846 : if (VAR_P (expr) && !lval && (optimize || in_init))
168 : {
169 14345644 : if (in_init)
170 466 : ret = decl_constant_value_1 (expr, true);
171 : else
172 : {
173 14345436 : ret = decl_constant_value (expr);
174 14345436 : if (ret != expr
175 14345436 : && (TYPE_MODE (TREE_TYPE (ret)) == BLKmode
176 15062 : || TREE_CODE (TREE_TYPE (ret)) == ARRAY_TYPE))
177 : return expr;
178 : }
179 : /* Avoid unwanted tree sharing between the initializer and current
180 : function's body where the tree can be modified e.g. by the
181 : gimplifier. */
182 14343373 : if (ret != expr && TREE_STATIC (expr))
183 5861 : ret = unshare_expr (ret);
184 14343373 : return ret;
185 : }
186 : return expr;
187 : }
188 :
189 256715070 : if (IS_EXPR_CODE_CLASS (kind))
190 256715070 : old_range = EXPR_LOCATION_RANGE (expr);
191 :
192 : /* Operands of variable-length expressions (function calls) have
193 : already been folded, as have __builtin_* function calls, and such
194 : expressions cannot occur in constant expressions. */
195 256715070 : if (kind == tcc_vl_exp)
196 : {
197 50174747 : *maybe_const_operands = false;
198 50174747 : ret = fold (expr);
199 50174747 : goto out;
200 : }
201 :
202 206540323 : if (code == C_MAYBE_CONST_EXPR)
203 : {
204 4539692 : tree pre = C_MAYBE_CONST_EXPR_PRE (expr);
205 4539692 : tree inner = C_MAYBE_CONST_EXPR_EXPR (expr);
206 4539692 : if (C_MAYBE_CONST_EXPR_NON_CONST (expr))
207 2171567 : *maybe_const_operands = false;
208 4539692 : if (C_MAYBE_CONST_EXPR_INT_OPERANDS (expr))
209 : {
210 1714 : *maybe_const_itself = false;
211 1714 : inner = c_fully_fold_internal (inner, in_init, maybe_const_operands,
212 : maybe_const_itself, true, lval);
213 : }
214 4539692 : if (pre && !in_init)
215 667 : ret = build2 (COMPOUND_EXPR, TREE_TYPE (expr), pre, inner);
216 : else
217 : ret = inner;
218 4539692 : goto out;
219 : }
220 :
221 : /* Assignment, increment, decrement, function call and comma
222 : operators, and statement expressions, cannot occur in constant
223 : expressions if evaluated / outside of sizeof. (Function calls
224 : were handled above, though VA_ARG_EXPR is treated like a function
225 : call here, and statement expressions are handled through
226 : C_MAYBE_CONST_EXPR to avoid folding inside them.) */
227 202000631 : switch (code)
228 : {
229 4149957 : case MODIFY_EXPR:
230 4149957 : case PREDECREMENT_EXPR:
231 4149957 : case PREINCREMENT_EXPR:
232 4149957 : case POSTDECREMENT_EXPR:
233 4149957 : case POSTINCREMENT_EXPR:
234 4149957 : case COMPOUND_EXPR:
235 4149957 : *maybe_const_operands = false;
236 4149957 : break;
237 :
238 139621 : case VA_ARG_EXPR:
239 139621 : case TARGET_EXPR:
240 139621 : case BIND_EXPR:
241 139621 : case OBJ_TYPE_REF:
242 139621 : *maybe_const_operands = false;
243 139621 : ret = fold (expr);
244 139621 : goto out;
245 :
246 : default:
247 : break;
248 : }
249 :
250 : /* Fold individual tree codes as appropriate. */
251 201861010 : switch (code)
252 : {
253 919363 : case COMPOUND_LITERAL_EXPR:
254 : /* Any non-constancy will have been marked in a containing
255 : C_MAYBE_CONST_EXPR; there is no more folding to do here. */
256 919363 : goto out;
257 :
258 2818226 : case COMPONENT_REF:
259 2818226 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
260 2818226 : op1 = TREE_OPERAND (expr, 1);
261 2818226 : op2 = TREE_OPERAND (expr, 2);
262 2818226 : op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
263 : maybe_const_itself, for_int_const, lval);
264 5636452 : STRIP_TYPE_NOPS (op0);
265 2818226 : if (op0 != orig_op0)
266 10363 : ret = build3 (COMPONENT_REF, TREE_TYPE (expr), op0, op1, op2);
267 2818226 : if (ret != expr)
268 : {
269 10363 : TREE_READONLY (ret) = TREE_READONLY (expr);
270 10363 : TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
271 : }
272 2818226 : if (!lval)
273 2047763 : ret = fold (ret);
274 2818226 : goto out;
275 :
276 2920998 : case ARRAY_REF:
277 2920998 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
278 2920998 : orig_op1 = op1 = TREE_OPERAND (expr, 1);
279 2920998 : op2 = TREE_OPERAND (expr, 2);
280 2920998 : op3 = TREE_OPERAND (expr, 3);
281 2920998 : op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
282 : maybe_const_itself, for_int_const, lval);
283 5841996 : STRIP_TYPE_NOPS (op0);
284 2920998 : op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
285 : maybe_const_itself, for_int_const, false);
286 5841996 : STRIP_TYPE_NOPS (op1);
287 : /* Fold "foo"[2] in initializers. */
288 2920998 : if (!lval && in_init)
289 : {
290 812 : ret = c_fold_array_ref (TREE_TYPE (expr), op0, op1);
291 812 : if (ret)
292 789 : goto out;
293 : ret = expr;
294 : }
295 2920209 : if (op0 != orig_op0 || op1 != orig_op1)
296 133842 : ret = build4 (ARRAY_REF, TREE_TYPE (expr), op0, op1, op2, op3);
297 2920209 : if (ret != expr)
298 : {
299 133842 : TREE_READONLY (ret) = TREE_READONLY (expr);
300 133842 : TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr);
301 133842 : TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
302 : }
303 2920209 : if (!lval)
304 2348453 : ret = fold (ret);
305 2920209 : goto out;
306 :
307 3890633 : case MODIFY_EXPR:
308 3890633 : case PREDECREMENT_EXPR:
309 3890633 : case PREINCREMENT_EXPR:
310 3890633 : case POSTDECREMENT_EXPR:
311 3890633 : case POSTINCREMENT_EXPR:
312 3890633 : op0_lval = true;
313 : /* FALLTHRU */
314 13625812 : case COMPOUND_EXPR:
315 13625812 : case PLUS_EXPR:
316 13625812 : case MINUS_EXPR:
317 13625812 : case MULT_EXPR:
318 13625812 : case POINTER_PLUS_EXPR:
319 13625812 : case POINTER_DIFF_EXPR:
320 13625812 : case TRUNC_DIV_EXPR:
321 13625812 : case CEIL_DIV_EXPR:
322 13625812 : case FLOOR_DIV_EXPR:
323 13625812 : case TRUNC_MOD_EXPR:
324 13625812 : case RDIV_EXPR:
325 13625812 : case EXACT_DIV_EXPR:
326 13625812 : case LSHIFT_EXPR:
327 13625812 : case RSHIFT_EXPR:
328 13625812 : case LROTATE_EXPR:
329 13625812 : case RROTATE_EXPR:
330 13625812 : case BIT_IOR_EXPR:
331 13625812 : case BIT_XOR_EXPR:
332 13625812 : case BIT_AND_EXPR:
333 13625812 : case LT_EXPR:
334 13625812 : case LE_EXPR:
335 13625812 : case GT_EXPR:
336 13625812 : case GE_EXPR:
337 13625812 : case EQ_EXPR:
338 13625812 : case NE_EXPR:
339 13625812 : case COMPLEX_EXPR:
340 13625812 : case TRUTH_AND_EXPR:
341 13625812 : case TRUTH_OR_EXPR:
342 13625812 : case TRUTH_XOR_EXPR:
343 13625812 : case UNORDERED_EXPR:
344 13625812 : case ORDERED_EXPR:
345 13625812 : case UNLT_EXPR:
346 13625812 : case UNLE_EXPR:
347 13625812 : case UNGT_EXPR:
348 13625812 : case UNGE_EXPR:
349 13625812 : case UNEQ_EXPR:
350 13625812 : case MEM_REF:
351 : /* Binary operations evaluating both arguments (increment and
352 : decrement are binary internally in GCC). */
353 13625812 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
354 13625812 : orig_op1 = op1 = TREE_OPERAND (expr, 1);
355 13625812 : op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
356 : maybe_const_itself, for_int_const,
357 : op0_lval);
358 27251624 : STRIP_TYPE_NOPS (op0);
359 : /* The RHS of a MODIFY_EXPR was fully folded when building that
360 : expression for the sake of conversion warnings. */
361 13625812 : if (code != MODIFY_EXPR)
362 10675732 : op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
363 : maybe_const_itself, for_int_const, false);
364 13625863 : STRIP_TYPE_NOPS (op1);
365 :
366 13625812 : if (for_int_const && (TREE_CODE (op0) != INTEGER_CST
367 1280 : || TREE_CODE (op1) != INTEGER_CST))
368 273 : goto out;
369 :
370 13625539 : if (TREE_CODE_CLASS (code) == tcc_comparison
371 2468094 : && TREE_CODE (TREE_TYPE (op0)) == NULLPTR_TYPE
372 13625561 : && TREE_CODE (TREE_TYPE (op1)) == NULLPTR_TYPE)
373 : {
374 22 : switch (code)
375 : {
376 8 : case EQ_EXPR:
377 8 : ret = constant_boolean_node (true, TREE_TYPE (expr));
378 8 : break;
379 14 : case NE_EXPR:
380 14 : ret = constant_boolean_node (false, TREE_TYPE (expr));
381 14 : break;
382 0 : default:
383 0 : gcc_unreachable ();
384 : }
385 22 : ret = omit_two_operands_loc (loc, TREE_TYPE (expr), ret,
386 : op0, op1);
387 : }
388 13625517 : else if (op0 != orig_op0 || op1 != orig_op1 || in_init)
389 2553649 : ret = in_init
390 2555354 : ? fold_build2_initializer_loc (loc, code, TREE_TYPE (expr), op0, op1)
391 2551135 : : fold_build2_loc (loc, code, TREE_TYPE (expr), op0, op1);
392 : else
393 11070163 : ret = fold (expr);
394 268027 : if (TREE_OVERFLOW_P (ret)
395 22 : && !TREE_OVERFLOW_P (op0)
396 21 : && !(BINARY_CLASS_P (op0) && TREE_OVERFLOW_P (TREE_OPERAND (op0, 1)))
397 13625559 : && !TREE_OVERFLOW_P (op1))
398 19 : overflow_warning (EXPR_LOC_OR_LOC (expr, input_location), ret, expr);
399 13625539 : if (code == LSHIFT_EXPR
400 451331 : && TREE_CODE (orig_op0) != INTEGER_CST
401 366516 : && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
402 879 : || TREE_CODE (TREE_TYPE (orig_op0)) == BITINT_TYPE)
403 365975 : && TREE_CODE (op0) == INTEGER_CST
404 175 : && c_inhibit_evaluation_warnings == 0
405 76 : && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (orig_op0))
406 13625571 : && tree_int_cst_sgn (op0) < 0)
407 6 : warning_at (loc, OPT_Wshift_negative_value,
408 : "left shift of negative value");
409 13625539 : if ((code == LSHIFT_EXPR
410 : || code == RSHIFT_EXPR
411 : || code == LROTATE_EXPR
412 13625539 : || code == RROTATE_EXPR)
413 639414 : && TREE_CODE (orig_op1) != INTEGER_CST
414 145295 : && TREE_CODE (op1) == INTEGER_CST
415 521 : && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE
416 13626058 : && c_inhibit_evaluation_warnings == 0)
417 : {
418 329 : if (tree_int_cst_sgn (op1) < 0)
419 29 : warning_at (loc, OPT_Wshift_count_negative,
420 : (code == LSHIFT_EXPR
421 : ? G_("left shift count is negative")
422 : : G_("right shift count is negative")));
423 312 : else if ((TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
424 106 : || TREE_CODE (TREE_TYPE (orig_op0)) == BITINT_TYPE
425 12 : || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE)
426 300 : && compare_tree_int (op1,
427 300 : TYPE_PRECISION (TREE_TYPE (orig_op0)))
428 : >= 0
429 327 : && !warning_suppressed_p (expr, OPT_Wshift_count_overflow))
430 6 : warning_at (loc, OPT_Wshift_count_overflow,
431 : (code == LSHIFT_EXPR
432 : ? G_("left shift count >= width of type")
433 : : G_("right shift count >= width of type")));
434 308 : else if (TREE_CODE (TREE_TYPE (orig_op0)) == VECTOR_TYPE
435 320 : && compare_tree_int (op1,
436 12 : TYPE_PRECISION (TREE_TYPE (TREE_TYPE (orig_op0))))
437 : >= 0)
438 9 : warning_at (loc, OPT_Wshift_count_overflow,
439 : code == LSHIFT_EXPR
440 : ? G_("left shift count >= width of vector element")
441 : : G_("right shift count >= width of vector element"));
442 : }
443 13625539 : if (code == LSHIFT_EXPR
444 : /* If either OP0 has been folded to INTEGER_CST... */
445 451331 : && ((TREE_CODE (orig_op0) != INTEGER_CST
446 366516 : && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
447 879 : || TREE_CODE (TREE_TYPE (orig_op0)) == BITINT_TYPE)
448 365975 : && TREE_CODE (op0) == INTEGER_CST)
449 : /* ...or if OP1 has been folded to INTEGER_CST... */
450 451156 : || (TREE_CODE (orig_op1) != INTEGER_CST
451 113962 : && (TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE
452 292 : || TREE_CODE (TREE_TYPE (orig_op1)) == BITINT_TYPE)
453 113700 : && TREE_CODE (op1) == INTEGER_CST))
454 13625930 : && c_inhibit_evaluation_warnings == 0)
455 : /* ...then maybe we can detect an overflow. */
456 211 : maybe_warn_shift_overflow (loc, op0, op1);
457 13625539 : if ((code == TRUNC_DIV_EXPR
458 : || code == CEIL_DIV_EXPR
459 13625539 : || code == FLOOR_DIV_EXPR
460 13625539 : || code == EXACT_DIV_EXPR
461 : || code == TRUNC_MOD_EXPR)
462 89016 : && TREE_CODE (orig_op1) != INTEGER_CST
463 11692 : && TREE_CODE (op1) == INTEGER_CST
464 90 : && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
465 0 : || TREE_CODE (TREE_TYPE (orig_op0)) == BITINT_TYPE
466 0 : || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE)
467 90 : && (TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE
468 0 : || TREE_CODE (TREE_TYPE (orig_op1)) == BITINT_TYPE))
469 90 : warn_for_div_by_zero (loc, op1);
470 13625539 : if (code == MEM_REF
471 13625539 : && ret != expr
472 12335 : && TREE_CODE (ret) == MEM_REF)
473 : {
474 12335 : TREE_READONLY (ret) = TREE_READONLY (expr);
475 12335 : TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr);
476 12335 : TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
477 : }
478 13625539 : goto out;
479 :
480 52713091 : case ADDR_EXPR:
481 52713091 : op0_lval = true;
482 52713091 : goto unary;
483 94134952 : case REALPART_EXPR:
484 94134952 : case IMAGPART_EXPR:
485 94134952 : case VIEW_CONVERT_EXPR:
486 94134952 : op0_lval = lval;
487 : /* FALLTHRU */
488 180608200 : case INDIRECT_REF:
489 180608200 : case FIX_TRUNC_EXPR:
490 180608200 : case FLOAT_EXPR:
491 180608200 : CASE_CONVERT:
492 180608200 : case ADDR_SPACE_CONVERT_EXPR:
493 180608200 : case NON_LVALUE_EXPR:
494 180608200 : case NEGATE_EXPR:
495 180608200 : case BIT_NOT_EXPR:
496 180608200 : case TRUTH_NOT_EXPR:
497 180608200 : case CONJ_EXPR:
498 180608200 : case PAREN_EXPR:
499 180608200 : unary:
500 : /* Unary operations. */
501 180608200 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
502 180608200 : op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
503 : maybe_const_itself, for_int_const,
504 : op0_lval);
505 361216422 : STRIP_TYPE_NOPS (op0);
506 :
507 180608200 : if (for_int_const && TREE_CODE (op0) != INTEGER_CST)
508 14 : goto out;
509 :
510 : /* ??? Cope with user tricks that amount to offsetof. The middle-end is
511 : not prepared to deal with them if they occur in initializers. */
512 180608186 : if (op0 != orig_op0
513 180608186 : && code == ADDR_EXPR
514 517 : && (op1 = get_base_address (op0)) != NULL_TREE
515 517 : && INDIRECT_REF_P (op1)
516 180608349 : && TREE_CONSTANT (TREE_OPERAND (op1, 0)))
517 102 : ret = fold_offsetof (op0, TREE_TYPE (expr));
518 180608084 : else if (op0 != orig_op0 || in_init)
519 4177692 : ret = in_init
520 4177692 : ? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0)
521 1207546 : : fold_build1_loc (loc, code, TREE_TYPE (expr), op0);
522 : else
523 176430392 : ret = fold (expr);
524 180608186 : if (code == INDIRECT_REF
525 180608186 : && ret != expr
526 39011 : && INDIRECT_REF_P (ret))
527 : {
528 38913 : TREE_READONLY (ret) = TREE_READONLY (expr);
529 38913 : TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr);
530 38913 : TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
531 : }
532 180608186 : switch (code)
533 : {
534 : case FIX_TRUNC_EXPR:
535 : case FLOAT_EXPR:
536 : CASE_CONVERT:
537 : /* Don't warn about explicit conversions. We will already
538 : have warned about suspect implicit conversions. */
539 : break;
540 :
541 150948964 : default:
542 150948964 : if (TREE_OVERFLOW_P (ret) && !TREE_OVERFLOW_P (op0))
543 0 : overflow_warning (EXPR_LOCATION (expr), ret, op0);
544 : break;
545 : }
546 180608186 : goto out;
547 :
548 444941 : case TRUTH_ANDIF_EXPR:
549 444941 : case TRUTH_ORIF_EXPR:
550 : /* Binary operations not necessarily evaluating both
551 : arguments. */
552 444941 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
553 444941 : orig_op1 = op1 = TREE_OPERAND (expr, 1);
554 444941 : op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self,
555 : for_int_const, false);
556 889882 : STRIP_TYPE_NOPS (op0);
557 :
558 889882 : unused_p = (op0 == (code == TRUTH_ANDIF_EXPR
559 444941 : ? truthvalue_false_node
560 : : truthvalue_true_node));
561 444941 : c_disable_warnings (unused_p);
562 444941 : op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self,
563 : for_int_const, false);
564 889882 : STRIP_TYPE_NOPS (op1);
565 444941 : c_enable_warnings (unused_p);
566 :
567 444941 : if (for_int_const
568 50 : && (TREE_CODE (op0) != INTEGER_CST
569 : /* Require OP1 be an INTEGER_CST only if it's evaluated. */
570 36 : || (!unused_p && TREE_CODE (op1) != INTEGER_CST)))
571 40 : goto out;
572 :
573 444901 : if (op0 != orig_op0 || op1 != orig_op1 || in_init)
574 435332 : ret = in_init
575 435332 : ? fold_build2_initializer_loc (loc, code, TREE_TYPE (expr), op0, op1)
576 435317 : : fold_build2_loc (loc, code, TREE_TYPE (expr), op0, op1);
577 : else
578 9569 : ret = fold (expr);
579 444901 : *maybe_const_operands &= op0_const;
580 444901 : *maybe_const_itself &= op0_const_self;
581 787150 : if (!(flag_isoc99
582 441391 : && op0_const
583 342249 : && op0_const_self
584 : && (code == TRUTH_ANDIF_EXPR
585 127034 : ? op0 == truthvalue_false_node
586 215215 : : op0 == truthvalue_true_node)))
587 433411 : *maybe_const_operands &= op1_const;
588 789909 : if (!(op0_const
589 345008 : && op0_const_self
590 : && (code == TRUTH_ANDIF_EXPR
591 127318 : ? op0 == truthvalue_false_node
592 217690 : : op0 == truthvalue_true_node)))
593 433395 : *maybe_const_itself &= op1_const_self;
594 444901 : goto out;
595 :
596 262536 : case COND_EXPR:
597 262536 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
598 262536 : orig_op1 = op1 = TREE_OPERAND (expr, 1);
599 262536 : orig_op2 = op2 = TREE_OPERAND (expr, 2);
600 262536 : op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self,
601 : for_int_const, false);
602 :
603 525072 : STRIP_TYPE_NOPS (op0);
604 262536 : c_disable_warnings (op0 == truthvalue_false_node);
605 262536 : op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self,
606 : for_int_const, false);
607 525072 : STRIP_TYPE_NOPS (op1);
608 262536 : c_enable_warnings (op0 == truthvalue_false_node);
609 :
610 262536 : c_disable_warnings (op0 == truthvalue_true_node);
611 262536 : op2 = c_fully_fold_internal (op2, in_init, &op2_const, &op2_const_self,
612 : for_int_const, false);
613 525078 : STRIP_TYPE_NOPS (op2);
614 262536 : c_enable_warnings (op0 == truthvalue_true_node);
615 :
616 262577 : if (for_int_const
617 76 : && (TREE_CODE (op0) != INTEGER_CST
618 : /* Only the evaluated operand must be an INTEGER_CST. */
619 14 : || (op0 == truthvalue_true_node
620 14 : ? TREE_CODE (op1) != INTEGER_CST
621 27 : : TREE_CODE (op2) != INTEGER_CST)))
622 62 : goto out;
623 :
624 262474 : if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2)
625 206597 : ret = fold_build3_loc (loc, code, TREE_TYPE (expr), op0, op1, op2);
626 : else
627 55877 : ret = fold (expr);
628 262474 : *maybe_const_operands &= op0_const;
629 262474 : *maybe_const_itself &= op0_const_self;
630 262474 : if (!(flag_isoc99
631 261158 : && op0_const
632 187303 : && op0_const_self
633 187303 : && op0 == truthvalue_false_node))
634 247904 : *maybe_const_operands &= op1_const;
635 262474 : if (!(op0_const
636 188414 : && op0_const_self
637 188414 : && op0 == truthvalue_false_node))
638 247558 : *maybe_const_itself &= op1_const_self;
639 262474 : if (!(flag_isoc99
640 261158 : && op0_const
641 187303 : && op0_const_self
642 187303 : && op0 == truthvalue_true_node))
643 218898 : *maybe_const_operands &= op2_const;
644 262474 : if (!(op0_const
645 188414 : && op0_const_self
646 188414 : && op0 == truthvalue_true_node))
647 218783 : *maybe_const_itself &= op2_const_self;
648 262474 : goto out;
649 :
650 101038 : case VEC_COND_EXPR:
651 101038 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
652 101038 : orig_op1 = op1 = TREE_OPERAND (expr, 1);
653 101038 : orig_op2 = op2 = TREE_OPERAND (expr, 2);
654 101038 : op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
655 : maybe_const_itself, for_int_const, false);
656 202076 : STRIP_TYPE_NOPS (op0);
657 101038 : op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
658 : maybe_const_itself, for_int_const, false);
659 202076 : STRIP_TYPE_NOPS (op1);
660 101038 : op2 = c_fully_fold_internal (op2, in_init, maybe_const_operands,
661 : maybe_const_itself, for_int_const, false);
662 202076 : STRIP_TYPE_NOPS (op2);
663 :
664 101038 : if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2)
665 574 : ret = fold_build3_loc (loc, code, TREE_TYPE (expr), op0, op1, op2);
666 : else
667 100464 : ret = fold (expr);
668 101038 : goto out;
669 :
670 0 : case EXCESS_PRECISION_EXPR:
671 : /* Each case where an operand with excess precision may be
672 : encountered must remove the EXCESS_PRECISION_EXPR around
673 : inner operands and possibly put one around the whole
674 : expression or possibly convert to the semantic type (which
675 : c_fully_fold does); we cannot tell at this stage which is
676 : appropriate in any particular case. */
677 0 : gcc_unreachable ();
678 :
679 150380 : case SAVE_EXPR:
680 : /* Make sure to fold the contents of a SAVE_EXPR exactly once. */
681 150380 : op0 = TREE_OPERAND (expr, 0);
682 150380 : if (!SAVE_EXPR_FOLDED_P (expr))
683 : {
684 71204 : op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
685 : maybe_const_itself, for_int_const,
686 : false);
687 71204 : TREE_OPERAND (expr, 0) = op0;
688 71204 : SAVE_EXPR_FOLDED_P (expr) = true;
689 : }
690 : /* Return the SAVE_EXPR operand if it is invariant. */
691 150380 : if (tree_invariant_p (op0))
692 3390 : ret = op0;
693 150380 : goto out;
694 :
695 9516 : default:
696 : /* Various codes may appear through folding built-in functions
697 : and their arguments. */
698 9516 : goto out;
699 : }
700 :
701 256715070 : out:
702 : /* Some folding may introduce NON_LVALUE_EXPRs; all lvalue checks
703 : have been done by this point, so remove them again. */
704 256715070 : nowarning |= warning_suppressed_p (ret, OPT_Woverflow);
705 256890212 : STRIP_TYPE_NOPS (ret);
706 256715070 : if (nowarning && !warning_suppressed_p (ret, OPT_Woverflow))
707 : {
708 12295 : if (!CAN_HAVE_LOCATION_P (ret))
709 804 : ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
710 12295 : suppress_warning (ret, OPT_Woverflow);
711 : }
712 256715070 : if (ret != expr)
713 : {
714 13385373 : protected_set_expr_location (ret, loc);
715 13385373 : if (IS_EXPR_CODE_CLASS (kind))
716 13385373 : set_source_range (ret, old_range.m_start, old_range.m_finish);
717 : }
718 : return ret;
719 : }
720 :
721 : /* Fold X for consideration by one of the warning functions when checking
722 : whether an expression has a constant value. */
723 :
724 : tree
725 128780315 : fold_for_warn (tree x)
726 : {
727 : /* The C front-end has already folded X appropriately. */
728 128780315 : return x;
729 : }
|