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