Branch data Line data Source code
1 : : /* Support for fully folding sub-trees of an expression for C compiler.
2 : : Copyright (C) 1992-2025 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 : 924586 : c_disable_warnings (bool disable)
39 : : {
40 : 924586 : if (disable)
41 : : {
42 : 68625 : ++c_inhibit_evaluation_warnings;
43 : 68625 : fold_defer_overflow_warnings ();
44 : : }
45 : 924586 : }
46 : :
47 : : /* If ENABLE is true, reenable issuing warnings. */
48 : :
49 : : static void
50 : 924586 : c_enable_warnings (bool enable)
51 : : {
52 : 924586 : if (enable)
53 : : {
54 : 68625 : --c_inhibit_evaluation_warnings;
55 : 68625 : fold_undefer_and_ignore_overflow_warnings ();
56 : : }
57 : 924586 : }
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 : 274333488 : c_fully_fold (tree expr, bool in_init, bool *maybe_const, bool lval)
112 : : {
113 : 274333488 : tree ret;
114 : 274333488 : tree eptype = NULL_TREE;
115 : 274333488 : bool dummy = true;
116 : 274333488 : bool maybe_const_itself = true;
117 : 274333488 : location_t loc = EXPR_LOCATION (expr);
118 : :
119 : 274333488 : if (!maybe_const)
120 : 239516739 : maybe_const = &dummy;
121 : 274333488 : if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR)
122 : : {
123 : 742 : eptype = TREE_TYPE (expr);
124 : 742 : expr = TREE_OPERAND (expr, 0);
125 : : }
126 : 274333488 : ret = c_fully_fold_internal (expr, in_init, maybe_const,
127 : : &maybe_const_itself, false, lval);
128 : 274333488 : if (eptype)
129 : 742 : ret = fold_convert_loc (loc, eptype, ret);
130 : 274333488 : *maybe_const &= maybe_const_itself;
131 : 274333488 : 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 : 494788245 : 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 : 494788245 : tree ret = expr;
151 : 494788245 : enum tree_code code = TREE_CODE (expr);
152 : 494788245 : enum tree_code_class kind = TREE_CODE_CLASS (code);
153 : 494788245 : location_t loc = EXPR_LOCATION (expr);
154 : 494788245 : tree op0, op1, op2, op3;
155 : 494788245 : tree orig_op0, orig_op1, orig_op2;
156 : 494788245 : bool op0_const = true, op1_const = true, op2_const = true;
157 : 494788245 : bool op0_const_self = true, op1_const_self = true, op2_const_self = true;
158 : 494788245 : bool nowarning = warning_suppressed_p (expr, OPT_Woverflow);
159 : 494788245 : bool unused_p;
160 : 494788245 : bool op0_lval = false;
161 : 494788245 : 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 : 494788245 : if (!IS_EXPR_CODE_CLASS (kind) || kind == tcc_statement)
167 : : {
168 : : /* Except for variables which we can optimize to its initializer. */
169 : 232213546 : if (VAR_P (expr) && !lval && (optimize || in_init))
170 : : {
171 : 14074571 : if (in_init)
172 : 466 : ret = decl_constant_value_1 (expr, true);
173 : : else
174 : : {
175 : 14074363 : ret = decl_constant_value (expr);
176 : 14074363 : if (ret != expr
177 : 14074363 : && (TYPE_MODE (TREE_TYPE (ret)) == BLKmode
178 : 13980 : || 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 : 14072308 : if (ret != expr && TREE_STATIC (expr))
185 : 5924 : ret = unshare_expr (ret);
186 : 14072308 : return ret;
187 : : }
188 : : return expr;
189 : : }
190 : :
191 : 262574699 : if (IS_EXPR_CODE_CLASS (kind))
192 : 262574699 : 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 : 262574699 : if (kind == tcc_vl_exp)
198 : : {
199 : 50996264 : *maybe_const_operands = false;
200 : 50996264 : ret = fold (expr);
201 : 50996264 : goto out;
202 : : }
203 : :
204 : 211578435 : if (code == C_MAYBE_CONST_EXPR)
205 : : {
206 : 4416558 : tree pre = C_MAYBE_CONST_EXPR_PRE (expr);
207 : 4416558 : tree inner = C_MAYBE_CONST_EXPR_EXPR (expr);
208 : 4416558 : if (C_MAYBE_CONST_EXPR_NON_CONST (expr))
209 : 2125094 : *maybe_const_operands = false;
210 : 4416558 : if (C_MAYBE_CONST_EXPR_INT_OPERANDS (expr))
211 : : {
212 : 1714 : *maybe_const_itself = false;
213 : 1714 : inner = c_fully_fold_internal (inner, in_init, maybe_const_operands,
214 : : maybe_const_itself, true, lval);
215 : : }
216 : 4416558 : if (pre && !in_init)
217 : 592 : ret = build2 (COMPOUND_EXPR, TREE_TYPE (expr), pre, inner);
218 : : else
219 : : ret = inner;
220 : 4416558 : 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 : 207161877 : switch (code)
230 : : {
231 : 4063466 : case MODIFY_EXPR:
232 : 4063466 : case PREDECREMENT_EXPR:
233 : 4063466 : case PREINCREMENT_EXPR:
234 : 4063466 : case POSTDECREMENT_EXPR:
235 : 4063466 : case POSTINCREMENT_EXPR:
236 : 4063466 : case COMPOUND_EXPR:
237 : 4063466 : *maybe_const_operands = false;
238 : 4063466 : break;
239 : :
240 : 136147 : case VA_ARG_EXPR:
241 : 136147 : case TARGET_EXPR:
242 : 136147 : case BIND_EXPR:
243 : 136147 : case OBJ_TYPE_REF:
244 : 136147 : *maybe_const_operands = false;
245 : 136147 : ret = fold (expr);
246 : 136147 : goto out;
247 : :
248 : : default:
249 : : break;
250 : : }
251 : :
252 : : /* Fold individual tree codes as appropriate. */
253 : 207025730 : switch (code)
254 : : {
255 : 899275 : 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 : 899275 : goto out;
259 : :
260 : 2749897 : case COMPONENT_REF:
261 : 2749897 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
262 : 2749897 : op1 = TREE_OPERAND (expr, 1);
263 : 2749897 : op2 = TREE_OPERAND (expr, 2);
264 : 2749897 : op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
265 : : maybe_const_itself, for_int_const, lval);
266 : 5499794 : STRIP_TYPE_NOPS (op0);
267 : 2749897 : if (op0 != orig_op0)
268 : 10135 : ret = build3 (COMPONENT_REF, TREE_TYPE (expr), op0, op1, op2);
269 : 2749897 : if (ret != expr)
270 : : {
271 : 10135 : TREE_READONLY (ret) = TREE_READONLY (expr);
272 : 10135 : TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
273 : : }
274 : 2749897 : if (!lval)
275 : 1998917 : ret = fold (ret);
276 : 2749897 : goto out;
277 : :
278 : 2864800 : case ARRAY_REF:
279 : 2864800 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
280 : 2864800 : orig_op1 = op1 = TREE_OPERAND (expr, 1);
281 : 2864800 : op2 = TREE_OPERAND (expr, 2);
282 : 2864800 : op3 = TREE_OPERAND (expr, 3);
283 : 2864800 : op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
284 : : maybe_const_itself, for_int_const, lval);
285 : 5729600 : STRIP_TYPE_NOPS (op0);
286 : 2864800 : op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
287 : : maybe_const_itself, for_int_const, false);
288 : 5729600 : STRIP_TYPE_NOPS (op1);
289 : : /* Fold "foo"[2] in initializers. */
290 : 2864800 : 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 : 2864011 : if (op0 != orig_op0 || op1 != orig_op1)
298 : 131327 : ret = build4 (ARRAY_REF, TREE_TYPE (expr), op0, op1, op2, op3);
299 : 2864011 : if (ret != expr)
300 : : {
301 : 131327 : TREE_READONLY (ret) = TREE_READONLY (expr);
302 : 131327 : TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr);
303 : 131327 : TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
304 : : }
305 : 2864011 : if (!lval)
306 : 2300188 : ret = fold (ret);
307 : 2864011 : goto out;
308 : :
309 : 3815993 : case MODIFY_EXPR:
310 : 3815993 : case PREDECREMENT_EXPR:
311 : 3815993 : case PREINCREMENT_EXPR:
312 : 3815993 : case POSTDECREMENT_EXPR:
313 : 3815993 : case POSTINCREMENT_EXPR:
314 : 3815993 : op0_lval = true;
315 : : /* FALLTHRU */
316 : 13337582 : case COMPOUND_EXPR:
317 : 13337582 : case PLUS_EXPR:
318 : 13337582 : case MINUS_EXPR:
319 : 13337582 : case MULT_EXPR:
320 : 13337582 : case POINTER_PLUS_EXPR:
321 : 13337582 : case POINTER_DIFF_EXPR:
322 : 13337582 : case TRUNC_DIV_EXPR:
323 : 13337582 : case CEIL_DIV_EXPR:
324 : 13337582 : case FLOOR_DIV_EXPR:
325 : 13337582 : case TRUNC_MOD_EXPR:
326 : 13337582 : case RDIV_EXPR:
327 : 13337582 : case EXACT_DIV_EXPR:
328 : 13337582 : case LSHIFT_EXPR:
329 : 13337582 : case RSHIFT_EXPR:
330 : 13337582 : case LROTATE_EXPR:
331 : 13337582 : case RROTATE_EXPR:
332 : 13337582 : case BIT_IOR_EXPR:
333 : 13337582 : case BIT_XOR_EXPR:
334 : 13337582 : case BIT_AND_EXPR:
335 : 13337582 : case LT_EXPR:
336 : 13337582 : case LE_EXPR:
337 : 13337582 : case GT_EXPR:
338 : 13337582 : case GE_EXPR:
339 : 13337582 : case EQ_EXPR:
340 : 13337582 : case NE_EXPR:
341 : 13337582 : case COMPLEX_EXPR:
342 : 13337582 : case TRUTH_AND_EXPR:
343 : 13337582 : case TRUTH_OR_EXPR:
344 : 13337582 : case TRUTH_XOR_EXPR:
345 : 13337582 : case UNORDERED_EXPR:
346 : 13337582 : case ORDERED_EXPR:
347 : 13337582 : case UNLT_EXPR:
348 : 13337582 : case UNLE_EXPR:
349 : 13337582 : case UNGT_EXPR:
350 : 13337582 : case UNGE_EXPR:
351 : 13337582 : case UNEQ_EXPR:
352 : 13337582 : case MEM_REF:
353 : : /* Binary operations evaluating both arguments (increment and
354 : : decrement are binary internally in GCC). */
355 : 13337582 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
356 : 13337582 : orig_op1 = op1 = TREE_OPERAND (expr, 1);
357 : 13337582 : op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
358 : : maybe_const_itself, for_int_const,
359 : : op0_lval);
360 : 26675164 : 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 : 13337582 : if (code != MODIFY_EXPR)
364 : 10422322 : op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
365 : : maybe_const_itself, for_int_const, false);
366 : 13337633 : STRIP_TYPE_NOPS (op1);
367 : :
368 : 13337582 : if (for_int_const && (TREE_CODE (op0) != INTEGER_CST
369 : 1289 : || TREE_CODE (op1) != INTEGER_CST))
370 : 271 : goto out;
371 : :
372 : 13337311 : if (op0 != orig_op0 || op1 != orig_op1 || in_init)
373 : 2452696 : ret = in_init
374 : 2454493 : ? fold_build2_initializer_loc (loc, code, TREE_TYPE (expr), op0, op1)
375 : 2450203 : : fold_build2_loc (loc, code, TREE_TYPE (expr), op0, op1);
376 : : else
377 : 10882818 : ret = fold (expr);
378 : 265693 : if (TREE_OVERFLOW_P (ret)
379 : 23 : && !TREE_OVERFLOW_P (op0)
380 : 22 : && !(BINARY_CLASS_P (op0) && TREE_OVERFLOW_P (TREE_OPERAND (op0, 1)))
381 : 13337332 : && !TREE_OVERFLOW_P (op1))
382 : 20 : overflow_warning (EXPR_LOC_OR_LOC (expr, input_location), ret, expr);
383 : 13337311 : if (code == LSHIFT_EXPR
384 : 479064 : && TREE_CODE (orig_op0) != INTEGER_CST
385 : 399095 : && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
386 : 829 : || TREE_CODE (TREE_TYPE (orig_op0)) == BITINT_TYPE)
387 : 398556 : && TREE_CODE (op0) == INTEGER_CST
388 : 190 : && c_inhibit_evaluation_warnings == 0
389 : 83 : && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (orig_op0))
390 : 13337350 : && tree_int_cst_sgn (op0) < 0)
391 : 6 : warning_at (loc, OPT_Wshift_negative_value,
392 : : "left shift of negative value");
393 : 13337311 : if ((code == LSHIFT_EXPR
394 : : || code == RSHIFT_EXPR
395 : : || code == LROTATE_EXPR
396 : 13337311 : || code == RROTATE_EXPR)
397 : 635660 : && TREE_CODE (orig_op1) != INTEGER_CST
398 : 139176 : && TREE_CODE (op1) == INTEGER_CST
399 : 516 : && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE
400 : 13337825 : && c_inhibit_evaluation_warnings == 0)
401 : : {
402 : 324 : if (tree_int_cst_sgn (op1) < 0)
403 : 29 : warning_at (loc, OPT_Wshift_count_negative,
404 : : (code == LSHIFT_EXPR
405 : : ? G_("left shift count is negative")
406 : : : G_("right shift count is negative")));
407 : 307 : else if ((TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
408 : 106 : || TREE_CODE (TREE_TYPE (orig_op0)) == BITINT_TYPE
409 : 12 : || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE)
410 : 295 : && compare_tree_int (op1,
411 : 295 : TYPE_PRECISION (TREE_TYPE (orig_op0)))
412 : : >= 0
413 : 322 : && !warning_suppressed_p (expr, OPT_Wshift_count_overflow))
414 : 6 : warning_at (loc, OPT_Wshift_count_overflow,
415 : : (code == LSHIFT_EXPR
416 : : ? G_("left shift count >= width of type")
417 : : : G_("right shift count >= width of type")));
418 : 303 : else if (TREE_CODE (TREE_TYPE (orig_op0)) == VECTOR_TYPE
419 : 315 : && compare_tree_int (op1,
420 : 12 : TYPE_PRECISION (TREE_TYPE (TREE_TYPE (orig_op0))))
421 : : >= 0)
422 : 9 : warning_at (loc, OPT_Wshift_count_overflow,
423 : : code == LSHIFT_EXPR
424 : : ? G_("left shift count >= width of vector element")
425 : : : G_("right shift count >= width of vector element"));
426 : : }
427 : 13337311 : if (code == LSHIFT_EXPR
428 : : /* If either OP0 has been folded to INTEGER_CST... */
429 : 479064 : && ((TREE_CODE (orig_op0) != INTEGER_CST
430 : 399095 : && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
431 : 829 : || TREE_CODE (TREE_TYPE (orig_op0)) == BITINT_TYPE)
432 : 398556 : && TREE_CODE (op0) == INTEGER_CST)
433 : : /* ...or if OP1 has been folded to INTEGER_CST... */
434 : 478874 : || (TREE_CODE (orig_op1) != INTEGER_CST
435 : 108486 : && (TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE
436 : 287 : || TREE_CODE (TREE_TYPE (orig_op1)) == BITINT_TYPE)
437 : 108224 : && TREE_CODE (op1) == INTEGER_CST))
438 : 13337715 : && c_inhibit_evaluation_warnings == 0)
439 : : /* ...then maybe we can detect an overflow. */
440 : 216 : maybe_warn_shift_overflow (loc, op0, op1);
441 : 13337311 : if ((code == TRUNC_DIV_EXPR
442 : : || code == CEIL_DIV_EXPR
443 : 13337311 : || code == FLOOR_DIV_EXPR
444 : 13337311 : || code == EXACT_DIV_EXPR
445 : : || code == TRUNC_MOD_EXPR)
446 : 99056 : && TREE_CODE (orig_op1) != INTEGER_CST
447 : 10712 : && TREE_CODE (op1) == INTEGER_CST
448 : 49 : && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
449 : 0 : || TREE_CODE (TREE_TYPE (orig_op0)) == BITINT_TYPE
450 : 0 : || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE)
451 : 49 : && (TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE
452 : 0 : || TREE_CODE (TREE_TYPE (orig_op1)) == BITINT_TYPE))
453 : 49 : warn_for_div_by_zero (loc, op1);
454 : 13337311 : if (code == MEM_REF
455 : 13337311 : && ret != expr
456 : 12288 : && TREE_CODE (ret) == MEM_REF)
457 : : {
458 : 12288 : TREE_READONLY (ret) = TREE_READONLY (expr);
459 : 12288 : TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr);
460 : 12288 : TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
461 : : }
462 : 13337311 : goto out;
463 : :
464 : 53514884 : case ADDR_EXPR:
465 : 53514884 : op0_lval = true;
466 : 53514884 : goto unary;
467 : 96800113 : case REALPART_EXPR:
468 : 96800113 : case IMAGPART_EXPR:
469 : 96800113 : case VIEW_CONVERT_EXPR:
470 : 96800113 : op0_lval = lval;
471 : : /* FALLTHRU */
472 : 186246708 : case INDIRECT_REF:
473 : 186246708 : case FIX_TRUNC_EXPR:
474 : 186246708 : case FLOAT_EXPR:
475 : 186246708 : CASE_CONVERT:
476 : 186246708 : case ADDR_SPACE_CONVERT_EXPR:
477 : 186246708 : case NON_LVALUE_EXPR:
478 : 186246708 : case NEGATE_EXPR:
479 : 186246708 : case BIT_NOT_EXPR:
480 : 186246708 : case TRUTH_NOT_EXPR:
481 : 186246708 : case CONJ_EXPR:
482 : 186246708 : case PAREN_EXPR:
483 : 186246708 : unary:
484 : : /* Unary operations. */
485 : 186246708 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
486 : 186246708 : op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
487 : : maybe_const_itself, for_int_const,
488 : : op0_lval);
489 : 372493438 : STRIP_TYPE_NOPS (op0);
490 : :
491 : 186246708 : if (for_int_const && TREE_CODE (op0) != INTEGER_CST)
492 : 14 : goto out;
493 : :
494 : : /* ??? Cope with user tricks that amount to offsetof. The middle-end is
495 : : not prepared to deal with them if they occur in initializers. */
496 : 186246694 : if (op0 != orig_op0
497 : 186246694 : && code == ADDR_EXPR
498 : 510 : && (op1 = get_base_address (op0)) != NULL_TREE
499 : 510 : && INDIRECT_REF_P (op1)
500 : 186246855 : && TREE_CONSTANT (TREE_OPERAND (op1, 0)))
501 : 102 : ret = fold_offsetof (op0, TREE_TYPE (expr));
502 : 186246592 : else if (op0 != orig_op0 || in_init)
503 : 4132329 : ret = in_init
504 : 4132329 : ? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0)
505 : 1162454 : : fold_build1_loc (loc, code, TREE_TYPE (expr), op0);
506 : : else
507 : 182114263 : ret = fold (expr);
508 : 186246694 : if (code == INDIRECT_REF
509 : 186246694 : && ret != expr
510 : 21993 : && INDIRECT_REF_P (ret))
511 : : {
512 : 21895 : TREE_READONLY (ret) = TREE_READONLY (expr);
513 : 21895 : TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr);
514 : 21895 : TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
515 : : }
516 : 186246694 : switch (code)
517 : : {
518 : : case FIX_TRUNC_EXPR:
519 : : case FLOAT_EXPR:
520 : : CASE_CONVERT:
521 : : /* Don't warn about explicit conversions. We will already
522 : : have warned about suspect implicit conversions. */
523 : : break;
524 : :
525 : 154290673 : default:
526 : 154290673 : if (TREE_OVERFLOW_P (ret) && !TREE_OVERFLOW_P (op0))
527 : 0 : overflow_warning (EXPR_LOCATION (expr), ret, op0);
528 : : break;
529 : : }
530 : 186246694 : goto out;
531 : :
532 : 432936 : case TRUTH_ANDIF_EXPR:
533 : 432936 : case TRUTH_ORIF_EXPR:
534 : : /* Binary operations not necessarily evaluating both
535 : : arguments. */
536 : 432936 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
537 : 432936 : orig_op1 = op1 = TREE_OPERAND (expr, 1);
538 : 432936 : op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self,
539 : : for_int_const, false);
540 : 865872 : STRIP_TYPE_NOPS (op0);
541 : :
542 : 865872 : unused_p = (op0 == (code == TRUTH_ANDIF_EXPR
543 : 432936 : ? truthvalue_false_node
544 : : : truthvalue_true_node));
545 : 432936 : c_disable_warnings (unused_p);
546 : 432936 : op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self,
547 : : for_int_const, false);
548 : 865872 : STRIP_TYPE_NOPS (op1);
549 : 432936 : c_enable_warnings (unused_p);
550 : :
551 : 432936 : if (for_int_const
552 : 50 : && (TREE_CODE (op0) != INTEGER_CST
553 : : /* Require OP1 be an INTEGER_CST only if it's evaluated. */
554 : 36 : || (!unused_p && TREE_CODE (op1) != INTEGER_CST)))
555 : 40 : goto out;
556 : :
557 : 432896 : if (op0 != orig_op0 || op1 != orig_op1 || in_init)
558 : 423630 : ret = in_init
559 : 423630 : ? fold_build2_initializer_loc (loc, code, TREE_TYPE (expr), op0, op1)
560 : 423615 : : fold_build2_loc (loc, code, TREE_TYPE (expr), op0, op1);
561 : : else
562 : 9266 : ret = fold (expr);
563 : 432896 : *maybe_const_operands &= op0_const;
564 : 432896 : *maybe_const_itself &= op0_const_self;
565 : 764502 : if (!(flag_isoc99
566 : 429398 : && op0_const
567 : 331606 : && op0_const_self
568 : : && (code == TRUTH_ANDIF_EXPR
569 : 119979 : ? op0 == truthvalue_false_node
570 : 211627 : : op0 == truthvalue_true_node)))
571 : 423350 : *maybe_const_operands &= op1_const;
572 : 767250 : if (!(op0_const
573 : 334354 : && op0_const_self
574 : : && (code == TRUTH_ANDIF_EXPR
575 : 120257 : ? op0 == truthvalue_false_node
576 : 214097 : : op0 == truthvalue_true_node)))
577 : 423334 : *maybe_const_itself &= op1_const_self;
578 : 432896 : goto out;
579 : :
580 : 245825 : case COND_EXPR:
581 : 245825 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
582 : 245825 : orig_op1 = op1 = TREE_OPERAND (expr, 1);
583 : 245825 : orig_op2 = op2 = TREE_OPERAND (expr, 2);
584 : 245825 : op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self,
585 : : for_int_const, false);
586 : :
587 : 491650 : STRIP_TYPE_NOPS (op0);
588 : 245825 : c_disable_warnings (op0 == truthvalue_false_node);
589 : 245825 : op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self,
590 : : for_int_const, false);
591 : 491650 : STRIP_TYPE_NOPS (op1);
592 : 245825 : c_enable_warnings (op0 == truthvalue_false_node);
593 : :
594 : 245825 : c_disable_warnings (op0 == truthvalue_true_node);
595 : 245825 : op2 = c_fully_fold_internal (op2, in_init, &op2_const, &op2_const_self,
596 : : for_int_const, false);
597 : 491656 : STRIP_TYPE_NOPS (op2);
598 : 245825 : c_enable_warnings (op0 == truthvalue_true_node);
599 : :
600 : 245825 : if (for_int_const
601 : 76 : && (TREE_CODE (op0) != INTEGER_CST
602 : : /* Only the evaluated operand must be an INTEGER_CST. */
603 : 41 : || (op0 == truthvalue_true_node
604 : 14 : ? TREE_CODE (op1) != INTEGER_CST
605 : 27 : : TREE_CODE (op2) != INTEGER_CST)))
606 : 62 : goto out;
607 : :
608 : 245763 : if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2)
609 : 196803 : ret = fold_build3_loc (loc, code, TREE_TYPE (expr), op0, op1, op2);
610 : : else
611 : 48960 : ret = fold (expr);
612 : 245763 : *maybe_const_operands &= op0_const;
613 : 245763 : *maybe_const_itself &= op0_const_self;
614 : 245763 : if (!(flag_isoc99
615 : 244453 : && op0_const
616 : 176021 : && op0_const_self
617 : 176021 : && op0 == truthvalue_false_node))
618 : 231193 : *maybe_const_operands &= op1_const;
619 : 245763 : if (!(op0_const
620 : 177123 : && op0_const_self
621 : 177123 : && op0 == truthvalue_false_node))
622 : 230847 : *maybe_const_itself &= op1_const_self;
623 : 245763 : if (!(flag_isoc99
624 : 244453 : && op0_const
625 : 176021 : && op0_const_self
626 : 176021 : && op0 == truthvalue_true_node))
627 : 202139 : *maybe_const_operands &= op2_const;
628 : 245763 : if (!(op0_const
629 : 177123 : && op0_const_self
630 : 177123 : && op0 == truthvalue_true_node))
631 : 202025 : *maybe_const_itself &= op2_const_self;
632 : 245763 : goto out;
633 : :
634 : 98865 : case VEC_COND_EXPR:
635 : 98865 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
636 : 98865 : orig_op1 = op1 = TREE_OPERAND (expr, 1);
637 : 98865 : orig_op2 = op2 = TREE_OPERAND (expr, 2);
638 : 98865 : op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
639 : : maybe_const_itself, for_int_const, false);
640 : 197730 : STRIP_TYPE_NOPS (op0);
641 : 98865 : op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
642 : : maybe_const_itself, for_int_const, false);
643 : 197730 : STRIP_TYPE_NOPS (op1);
644 : 98865 : op2 = c_fully_fold_internal (op2, in_init, maybe_const_operands,
645 : : maybe_const_itself, for_int_const, false);
646 : 197730 : STRIP_TYPE_NOPS (op2);
647 : :
648 : 98865 : if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2)
649 : 544 : ret = fold_build3_loc (loc, code, TREE_TYPE (expr), op0, op1, op2);
650 : : else
651 : 98321 : ret = fold (expr);
652 : 98865 : goto out;
653 : :
654 : 0 : case EXCESS_PRECISION_EXPR:
655 : : /* Each case where an operand with excess precision may be
656 : : encountered must remove the EXCESS_PRECISION_EXPR around
657 : : inner operands and possibly put one around the whole
658 : : expression or possibly convert to the semantic type (which
659 : : c_fully_fold does); we cannot tell at this stage which is
660 : : appropriate in any particular case. */
661 : 0 : gcc_unreachable ();
662 : :
663 : 141232 : case SAVE_EXPR:
664 : : /* Make sure to fold the contents of a SAVE_EXPR exactly once. */
665 : 141232 : op0 = TREE_OPERAND (expr, 0);
666 : 141232 : if (!SAVE_EXPR_FOLDED_P (expr))
667 : : {
668 : 66202 : op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
669 : : maybe_const_itself, for_int_const,
670 : : false);
671 : 66202 : TREE_OPERAND (expr, 0) = op0;
672 : 66202 : SAVE_EXPR_FOLDED_P (expr) = true;
673 : : }
674 : : /* Return the SAVE_EXPR operand if it is invariant. */
675 : 141232 : if (tree_invariant_p (op0))
676 : 3396 : ret = op0;
677 : 141232 : goto out;
678 : :
679 : 8610 : default:
680 : : /* Various codes may appear through folding built-in functions
681 : : and their arguments. */
682 : 8610 : goto out;
683 : : }
684 : :
685 : 262574699 : out:
686 : : /* Some folding may introduce NON_LVALUE_EXPRs; all lvalue checks
687 : : have been done by this point, so remove them again. */
688 : 262574699 : nowarning |= warning_suppressed_p (ret, OPT_Woverflow);
689 : 262744597 : STRIP_TYPE_NOPS (ret);
690 : 262574699 : if (nowarning && !warning_suppressed_p (ret, OPT_Woverflow))
691 : : {
692 : 10716 : if (!CAN_HAVE_LOCATION_P (ret))
693 : 804 : ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
694 : 10716 : suppress_warning (ret, OPT_Woverflow);
695 : : }
696 : 262574699 : if (ret != expr)
697 : : {
698 : 13049782 : protected_set_expr_location (ret, loc);
699 : 13049782 : if (IS_EXPR_CODE_CLASS (kind))
700 : 13049782 : set_source_range (ret, old_range.m_start, old_range.m_finish);
701 : : }
702 : : return ret;
703 : : }
704 : :
705 : : /* Fold X for consideration by one of the warning functions when checking
706 : : whether an expression has a constant value. */
707 : :
708 : : tree
709 : 132851318 : fold_for_warn (tree x)
710 : : {
711 : : /* The C front-end has already folded X appropriately. */
712 : 132851318 : return x;
713 : : }
|