Branch data Line data Source code
1 : : /* Support for fully folding sub-trees of an expression for C compiler.
2 : : Copyright (C) 1992-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 : : #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 : 905963 : c_disable_warnings (bool disable)
39 : : {
40 : 905963 : if (disable)
41 : : {
42 : 68565 : ++c_inhibit_evaluation_warnings;
43 : 68565 : fold_defer_overflow_warnings ();
44 : : }
45 : 905963 : }
46 : :
47 : : /* If ENABLE is true, reenable issuing warnings. */
48 : :
49 : : static void
50 : 905963 : c_enable_warnings (bool enable)
51 : : {
52 : 905963 : if (enable)
53 : : {
54 : 68565 : --c_inhibit_evaluation_warnings;
55 : 68565 : fold_undefer_and_ignore_overflow_warnings ();
56 : : }
57 : 905963 : }
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 : 810 : c_fold_array_ref (tree type, tree ary, tree index)
64 : : {
65 : 810 : 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 : 1601 : || !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 = array_type_nelts (TREE_TYPE (ary));
77 : 790 : bool dummy1 = true, dummy2 = true;
78 : 790 : nelts = c_fully_fold_internal (nelts, true, &dummy1, &dummy2, false, false);
79 : 790 : unsigned HOST_WIDE_INT i = tree_to_uhwi (index);
80 : 790 : if (!tree_int_cst_le (index, nelts)
81 : 789 : || i >= len
82 : 1579 : || i + elem_nchars > len)
83 : : return NULL_TREE;
84 : :
85 : 789 : if (elem_nchars == 1)
86 : 789 : return build_int_cst (type, TREE_STRING_POINTER (ary)[i]);
87 : :
88 : 0 : const unsigned char *ptr
89 : 0 : = ((const unsigned char *)TREE_STRING_POINTER (ary) + i * elem_nchars);
90 : 0 : return native_interpret_expr (type, ptr, elem_nchars);
91 : : }
92 : :
93 : : /* Fully fold EXPR, an expression that was not folded (beyond integer
94 : : constant expressions and null pointer constants) when being built
95 : : up. If IN_INIT, this is in a static initializer and certain
96 : : changes are made to the folding done. Clear *MAYBE_CONST if
97 : : MAYBE_CONST is not NULL and EXPR is definitely not a constant
98 : : expression because it contains an evaluated operator (in C99) or an
99 : : operator outside of sizeof returning an integer constant (in C90)
100 : : not permitted in constant expressions, or because it contains an
101 : : evaluated arithmetic overflow. (*MAYBE_CONST should typically be
102 : : set to true by callers before calling this function.) Return the
103 : : folded expression. Function arguments have already been folded
104 : : before calling this function, as have the contents of SAVE_EXPR,
105 : : TARGET_EXPR, BIND_EXPR, VA_ARG_EXPR, OBJ_TYPE_REF and
106 : : C_MAYBE_CONST_EXPR. LVAL is true if it should be treated as an
107 : : lvalue. */
108 : :
109 : : tree
110 : 241088656 : c_fully_fold (tree expr, bool in_init, bool *maybe_const, bool lval)
111 : : {
112 : 241088656 : tree ret;
113 : 241088656 : tree eptype = NULL_TREE;
114 : 241088656 : bool dummy = true;
115 : 241088656 : bool maybe_const_itself = true;
116 : 241088656 : location_t loc = EXPR_LOCATION (expr);
117 : :
118 : 241088656 : if (!maybe_const)
119 : 206725481 : maybe_const = &dummy;
120 : 241088656 : if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR)
121 : : {
122 : 708 : eptype = TREE_TYPE (expr);
123 : 708 : expr = TREE_OPERAND (expr, 0);
124 : : }
125 : 241088656 : ret = c_fully_fold_internal (expr, in_init, maybe_const,
126 : : &maybe_const_itself, false, lval);
127 : 241088656 : if (eptype)
128 : 708 : ret = fold_convert_loc (loc, eptype, ret);
129 : 241088656 : *maybe_const &= maybe_const_itself;
130 : 241088656 : return ret;
131 : : }
132 : :
133 : : /* Internal helper for c_fully_fold. EXPR and IN_INIT are as for
134 : : c_fully_fold. *MAYBE_CONST_OPERANDS is cleared because of operands
135 : : not permitted, while *MAYBE_CONST_ITSELF is cleared because of
136 : : arithmetic overflow (for C90, *MAYBE_CONST_OPERANDS is carried from
137 : : both evaluated and unevaluated subexpressions while
138 : : *MAYBE_CONST_ITSELF is carried from only evaluated
139 : : subexpressions). FOR_INT_CONST indicates if EXPR is an expression
140 : : with integer constant operands, and if any of the operands doesn't
141 : : get folded to an integer constant, don't fold the expression itself.
142 : : LVAL indicates folding of lvalue, where we can't replace it with
143 : : an rvalue. */
144 : :
145 : : static tree
146 : 432282470 : c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
147 : : bool *maybe_const_itself, bool for_int_const, bool lval)
148 : : {
149 : 432282470 : tree ret = expr;
150 : 432282470 : enum tree_code code = TREE_CODE (expr);
151 : 432282470 : enum tree_code_class kind = TREE_CODE_CLASS (code);
152 : 432282470 : location_t loc = EXPR_LOCATION (expr);
153 : 432282470 : tree op0, op1, op2, op3;
154 : 432282470 : tree orig_op0, orig_op1, orig_op2;
155 : 432282470 : bool op0_const = true, op1_const = true, op2_const = true;
156 : 432282470 : bool op0_const_self = true, op1_const_self = true, op2_const_self = true;
157 : 432282470 : bool nowarning = warning_suppressed_p (expr, OPT_Woverflow);
158 : 432282470 : bool unused_p;
159 : 432282470 : bool op0_lval = false;
160 : 432282470 : source_range old_range;
161 : :
162 : : /* Constants, declarations, statements, errors, and anything else not
163 : : counted as an expression cannot usefully be folded further at this
164 : : point. */
165 : 432282470 : if (!IS_EXPR_CODE_CLASS (kind) || kind == tcc_statement)
166 : : {
167 : : /* Except for variables which we can optimize to its initializer. */
168 : 206120912 : if (VAR_P (expr) && !lval && (optimize || in_init))
169 : : {
170 : 13893048 : if (in_init)
171 : 428 : ret = decl_constant_value_1 (expr, true);
172 : : else
173 : : {
174 : 13892847 : ret = decl_constant_value (expr);
175 : 13892847 : if (ret != expr
176 : 13892847 : && (TYPE_MODE (TREE_TYPE (ret)) == BLKmode
177 : 13525 : || TREE_CODE (TREE_TYPE (ret)) == ARRAY_TYPE))
178 : : return expr;
179 : : }
180 : : /* Avoid unwanted tree sharing between the initializer and current
181 : : function's body where the tree can be modified e.g. by the
182 : : gimplifier. */
183 : 13890754 : if (ret != expr && TREE_STATIC (expr))
184 : 6012 : ret = unshare_expr (ret);
185 : 13890754 : return ret;
186 : : }
187 : : return expr;
188 : : }
189 : :
190 : 226161558 : if (IS_EXPR_CODE_CLASS (kind))
191 : 226161558 : old_range = EXPR_LOCATION_RANGE (expr);
192 : :
193 : : /* Operands of variable-length expressions (function calls) have
194 : : already been folded, as have __builtin_* function calls, and such
195 : : expressions cannot occur in constant expressions. */
196 : 226161558 : if (kind == tcc_vl_exp)
197 : : {
198 : 43504047 : *maybe_const_operands = false;
199 : 43504047 : ret = fold (expr);
200 : 43504047 : goto out;
201 : : }
202 : :
203 : 182657511 : if (code == C_MAYBE_CONST_EXPR)
204 : : {
205 : 4383938 : tree pre = C_MAYBE_CONST_EXPR_PRE (expr);
206 : 4383938 : tree inner = C_MAYBE_CONST_EXPR_EXPR (expr);
207 : 4383938 : if (C_MAYBE_CONST_EXPR_NON_CONST (expr))
208 : 2110542 : *maybe_const_operands = false;
209 : 4383938 : if (C_MAYBE_CONST_EXPR_INT_OPERANDS (expr))
210 : : {
211 : 15666 : *maybe_const_itself = false;
212 : 15666 : inner = c_fully_fold_internal (inner, in_init, maybe_const_operands,
213 : : maybe_const_itself, true, lval);
214 : : }
215 : 4383938 : if (pre && !in_init)
216 : 546 : ret = build2 (COMPOUND_EXPR, TREE_TYPE (expr), pre, inner);
217 : : else
218 : : ret = inner;
219 : 4383938 : goto out;
220 : : }
221 : :
222 : : /* Assignment, increment, decrement, function call and comma
223 : : operators, and statement expressions, cannot occur in constant
224 : : expressions if evaluated / outside of sizeof. (Function calls
225 : : were handled above, though VA_ARG_EXPR is treated like a function
226 : : call here, and statement expressions are handled through
227 : : C_MAYBE_CONST_EXPR to avoid folding inside them.) */
228 : 178273573 : switch (code)
229 : : {
230 : 3971415 : case MODIFY_EXPR:
231 : 3971415 : case PREDECREMENT_EXPR:
232 : 3971415 : case PREINCREMENT_EXPR:
233 : 3971415 : case POSTDECREMENT_EXPR:
234 : 3971415 : case POSTINCREMENT_EXPR:
235 : 3971415 : case COMPOUND_EXPR:
236 : 3971415 : *maybe_const_operands = false;
237 : 3971415 : break;
238 : :
239 : 136015 : case VA_ARG_EXPR:
240 : 136015 : case TARGET_EXPR:
241 : 136015 : case BIND_EXPR:
242 : 136015 : case OBJ_TYPE_REF:
243 : 136015 : *maybe_const_operands = false;
244 : 136015 : ret = fold (expr);
245 : 136015 : goto out;
246 : :
247 : : default:
248 : : break;
249 : : }
250 : :
251 : : /* Fold individual tree codes as appropriate. */
252 : 178137558 : switch (code)
253 : : {
254 : 869078 : case COMPOUND_LITERAL_EXPR:
255 : : /* Any non-constancy will have been marked in a containing
256 : : C_MAYBE_CONST_EXPR; there is no more folding to do here. */
257 : 869078 : goto out;
258 : :
259 : 2732697 : case COMPONENT_REF:
260 : 2732697 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
261 : 2732697 : op1 = TREE_OPERAND (expr, 1);
262 : 2732697 : op2 = TREE_OPERAND (expr, 2);
263 : 2732697 : op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
264 : : maybe_const_itself, for_int_const, lval);
265 : 5465394 : STRIP_TYPE_NOPS (op0);
266 : 2732697 : if (op0 != orig_op0)
267 : 9356 : ret = build3 (COMPONENT_REF, TREE_TYPE (expr), op0, op1, op2);
268 : 2732697 : if (ret != expr)
269 : : {
270 : 9356 : TREE_READONLY (ret) = TREE_READONLY (expr);
271 : 9356 : TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
272 : : }
273 : 2732697 : if (!lval)
274 : 1994363 : ret = fold (ret);
275 : 2732697 : goto out;
276 : :
277 : 2803068 : case ARRAY_REF:
278 : 2803068 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
279 : 2803068 : orig_op1 = op1 = TREE_OPERAND (expr, 1);
280 : 2803068 : op2 = TREE_OPERAND (expr, 2);
281 : 2803068 : op3 = TREE_OPERAND (expr, 3);
282 : 2803068 : op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
283 : : maybe_const_itself, for_int_const, lval);
284 : 5606136 : STRIP_TYPE_NOPS (op0);
285 : 2803068 : op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
286 : : maybe_const_itself, for_int_const, false);
287 : 5606136 : STRIP_TYPE_NOPS (op1);
288 : : /* Fold "foo"[2] in initializers. */
289 : 2803068 : if (!lval && in_init)
290 : : {
291 : 810 : ret = c_fold_array_ref (TREE_TYPE (expr), op0, op1);
292 : 810 : if (ret)
293 : 789 : goto out;
294 : : ret = expr;
295 : : }
296 : 2802279 : if (op0 != orig_op0 || op1 != orig_op1)
297 : 102807 : ret = build4 (ARRAY_REF, TREE_TYPE (expr), op0, op1, op2, op3);
298 : 2802279 : if (ret != expr)
299 : : {
300 : 102807 : TREE_READONLY (ret) = TREE_READONLY (expr);
301 : 102807 : TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr);
302 : 102807 : TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
303 : : }
304 : 2802279 : if (!lval)
305 : 2249926 : ret = fold (ret);
306 : 2802279 : goto out;
307 : :
308 : 3725473 : case MODIFY_EXPR:
309 : 3725473 : case PREDECREMENT_EXPR:
310 : 3725473 : case PREINCREMENT_EXPR:
311 : 3725473 : case POSTDECREMENT_EXPR:
312 : 3725473 : case POSTINCREMENT_EXPR:
313 : 3725473 : op0_lval = true;
314 : : /* FALLTHRU */
315 : 12937185 : case COMPOUND_EXPR:
316 : 12937185 : case PLUS_EXPR:
317 : 12937185 : case MINUS_EXPR:
318 : 12937185 : case MULT_EXPR:
319 : 12937185 : case POINTER_PLUS_EXPR:
320 : 12937185 : case POINTER_DIFF_EXPR:
321 : 12937185 : case TRUNC_DIV_EXPR:
322 : 12937185 : case CEIL_DIV_EXPR:
323 : 12937185 : case FLOOR_DIV_EXPR:
324 : 12937185 : case TRUNC_MOD_EXPR:
325 : 12937185 : case RDIV_EXPR:
326 : 12937185 : case EXACT_DIV_EXPR:
327 : 12937185 : case LSHIFT_EXPR:
328 : 12937185 : case RSHIFT_EXPR:
329 : 12937185 : case BIT_IOR_EXPR:
330 : 12937185 : case BIT_XOR_EXPR:
331 : 12937185 : case BIT_AND_EXPR:
332 : 12937185 : case LT_EXPR:
333 : 12937185 : case LE_EXPR:
334 : 12937185 : case GT_EXPR:
335 : 12937185 : case GE_EXPR:
336 : 12937185 : case EQ_EXPR:
337 : 12937185 : case NE_EXPR:
338 : 12937185 : case COMPLEX_EXPR:
339 : 12937185 : case TRUTH_AND_EXPR:
340 : 12937185 : case TRUTH_OR_EXPR:
341 : 12937185 : case TRUTH_XOR_EXPR:
342 : 12937185 : case UNORDERED_EXPR:
343 : 12937185 : case ORDERED_EXPR:
344 : 12937185 : case UNLT_EXPR:
345 : 12937185 : case UNLE_EXPR:
346 : 12937185 : case UNGT_EXPR:
347 : 12937185 : case UNGE_EXPR:
348 : 12937185 : case UNEQ_EXPR:
349 : 12937185 : case MEM_REF:
350 : : /* Binary operations evaluating both arguments (increment and
351 : : decrement are binary internally in GCC). */
352 : 12937185 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
353 : 12937185 : orig_op1 = op1 = TREE_OPERAND (expr, 1);
354 : 12937185 : op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
355 : : maybe_const_itself, for_int_const,
356 : : op0_lval);
357 : 25874370 : STRIP_TYPE_NOPS (op0);
358 : : /* The RHS of a MODIFY_EXPR was fully folded when building that
359 : : expression for the sake of conversion warnings. */
360 : 12937185 : if (code != MODIFY_EXPR)
361 : 10104019 : op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
362 : : maybe_const_itself, for_int_const, false);
363 : 12937188 : STRIP_TYPE_NOPS (op1);
364 : :
365 : 12937185 : if (for_int_const && (TREE_CODE (op0) != INTEGER_CST
366 : 1253 : || TREE_CODE (op1) != INTEGER_CST))
367 : 263 : goto out;
368 : :
369 : 12936922 : if (op0 != orig_op0 || op1 != orig_op1 || in_init)
370 : 2420963 : ret = in_init
371 : 2422708 : ? fold_build2_initializer_loc (loc, code, TREE_TYPE (expr), op0, op1)
372 : 2418504 : : fold_build2_loc (loc, code, TREE_TYPE (expr), op0, op1);
373 : : else
374 : 10514214 : ret = fold (expr);
375 : 263802 : if (TREE_OVERFLOW_P (ret)
376 : 23 : && !TREE_OVERFLOW_P (op0)
377 : 22 : && !(BINARY_CLASS_P (op0) && TREE_OVERFLOW_P (TREE_OPERAND (op0, 1)))
378 : 12936943 : && !TREE_OVERFLOW_P (op1))
379 : 20 : overflow_warning (EXPR_LOC_OR_LOC (expr, input_location), ret, expr);
380 : 12936922 : if (code == LSHIFT_EXPR
381 : 378664 : && TREE_CODE (orig_op0) != INTEGER_CST
382 : 315045 : && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
383 : 802 : || TREE_CODE (TREE_TYPE (orig_op0)) == BITINT_TYPE)
384 : 314521 : && TREE_CODE (op0) == INTEGER_CST
385 : 190 : && c_inhibit_evaluation_warnings == 0
386 : 83 : && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (orig_op0))
387 : 12936961 : && tree_int_cst_sgn (op0) < 0)
388 : 6 : warning_at (loc, OPT_Wshift_negative_value,
389 : : "left shift of negative value");
390 : 12936922 : if ((code == LSHIFT_EXPR || code == RSHIFT_EXPR)
391 : 533207 : && TREE_CODE (orig_op1) != INTEGER_CST
392 : 122002 : && TREE_CODE (op1) == INTEGER_CST
393 : 216 : && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE
394 : 12937138 : && c_inhibit_evaluation_warnings == 0)
395 : : {
396 : 149 : if (tree_int_cst_sgn (op1) < 0)
397 : 29 : warning_at (loc, OPT_Wshift_count_negative,
398 : : (code == LSHIFT_EXPR
399 : : ? G_("left shift count is negative")
400 : : : G_("right shift count is negative")));
401 : 132 : else if ((TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
402 : 30 : || TREE_CODE (TREE_TYPE (orig_op0)) == BITINT_TYPE
403 : 12 : || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE)
404 : 252 : && compare_tree_int (op1,
405 : 120 : TYPE_PRECISION (TREE_TYPE (orig_op0)))
406 : : >= 0)
407 : 6 : warning_at (loc, OPT_Wshift_count_overflow,
408 : : (code == LSHIFT_EXPR
409 : : ? G_("left shift count >= width of type")
410 : : : G_("right shift count >= width of type")));
411 : 128 : else if (TREE_CODE (TREE_TYPE (orig_op0)) == VECTOR_TYPE
412 : 140 : && compare_tree_int (op1,
413 : 12 : TYPE_PRECISION (TREE_TYPE (TREE_TYPE (orig_op0))))
414 : : >= 0)
415 : 9 : warning_at (loc, OPT_Wshift_count_overflow,
416 : : code == LSHIFT_EXPR
417 : : ? G_("left shift count >= width of vector element")
418 : : : G_("right shift count >= width of vector element"));
419 : : }
420 : 12936922 : if (code == LSHIFT_EXPR
421 : : /* If either OP0 has been folded to INTEGER_CST... */
422 : 378664 : && ((TREE_CODE (orig_op0) != INTEGER_CST
423 : 315045 : && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
424 : 802 : || TREE_CODE (TREE_TYPE (orig_op0)) == BITINT_TYPE)
425 : 314521 : && TREE_CODE (op0) == INTEGER_CST)
426 : : /* ...or if OP1 has been folded to INTEGER_CST... */
427 : 378474 : || (TREE_CODE (orig_op1) != INTEGER_CST
428 : 91906 : && (TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE
429 : 277 : || TREE_CODE (TREE_TYPE (orig_op1)) == BITINT_TYPE)
430 : 91654 : && TREE_CODE (op1) == INTEGER_CST))
431 : 12937272 : && c_inhibit_evaluation_warnings == 0)
432 : : /* ...then maybe we can detect an overflow. */
433 : 183 : maybe_warn_shift_overflow (loc, op0, op1);
434 : 12936922 : if ((code == TRUNC_DIV_EXPR
435 : : || code == CEIL_DIV_EXPR
436 : 12936922 : || code == FLOOR_DIV_EXPR
437 : 12936922 : || code == EXACT_DIV_EXPR
438 : : || code == TRUNC_MOD_EXPR)
439 : 97579 : && TREE_CODE (orig_op1) != INTEGER_CST
440 : 10601 : && TREE_CODE (op1) == INTEGER_CST
441 : 45 : && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
442 : 0 : || TREE_CODE (TREE_TYPE (orig_op0)) == BITINT_TYPE
443 : 0 : || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE)
444 : 45 : && (TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE
445 : 0 : || TREE_CODE (TREE_TYPE (orig_op1)) == BITINT_TYPE))
446 : 45 : warn_for_div_by_zero (loc, op1);
447 : 12936922 : if (code == MEM_REF
448 : 12936922 : && ret != expr
449 : 12286 : && TREE_CODE (ret) == MEM_REF)
450 : : {
451 : 12286 : TREE_READONLY (ret) = TREE_READONLY (expr);
452 : 12286 : TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr);
453 : 12286 : TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
454 : : }
455 : 12936922 : goto out;
456 : :
457 : 46033922 : case ADDR_EXPR:
458 : 46033922 : op0_lval = true;
459 : 46033922 : goto unary;
460 : 81996944 : case REALPART_EXPR:
461 : 81996944 : case IMAGPART_EXPR:
462 : 81996944 : case VIEW_CONVERT_EXPR:
463 : 81996944 : op0_lval = lval;
464 : : /* FALLTHRU */
465 : 157844605 : case INDIRECT_REF:
466 : 157844605 : case FIX_TRUNC_EXPR:
467 : 157844605 : case FLOAT_EXPR:
468 : 157844605 : CASE_CONVERT:
469 : 157844605 : case ADDR_SPACE_CONVERT_EXPR:
470 : 157844605 : case NON_LVALUE_EXPR:
471 : 157844605 : case NEGATE_EXPR:
472 : 157844605 : case BIT_NOT_EXPR:
473 : 157844605 : case TRUTH_NOT_EXPR:
474 : 157844605 : case CONJ_EXPR:
475 : 157844605 : case PAREN_EXPR:
476 : 157844605 : unary:
477 : : /* Unary operations. */
478 : 157844605 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
479 : 157844605 : op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
480 : : maybe_const_itself, for_int_const,
481 : : op0_lval);
482 : 315689231 : STRIP_TYPE_NOPS (op0);
483 : :
484 : 157844605 : if (for_int_const && TREE_CODE (op0) != INTEGER_CST)
485 : 14 : goto out;
486 : :
487 : : /* ??? Cope with user tricks that amount to offsetof. The middle-end is
488 : : not prepared to deal with them if they occur in initializers. */
489 : 157844591 : if (op0 != orig_op0
490 : 157844591 : && code == ADDR_EXPR
491 : 501 : && (op1 = get_base_address (op0)) != NULL_TREE
492 : 501 : && INDIRECT_REF_P (op1)
493 : 157844752 : && TREE_CONSTANT (TREE_OPERAND (op1, 0)))
494 : 102 : ret = fold_offsetof (op0, TREE_TYPE (expr));
495 : 157844489 : else if (op0 != orig_op0 || in_init)
496 : 4092578 : ret = in_init
497 : 4092578 : ? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0)
498 : 1123068 : : fold_build1_loc (loc, code, TREE_TYPE (expr), op0);
499 : : else
500 : 153751911 : ret = fold (expr);
501 : 157844591 : if (code == INDIRECT_REF
502 : 157844591 : && ret != expr
503 : 21328 : && INDIRECT_REF_P (ret))
504 : : {
505 : 21230 : TREE_READONLY (ret) = TREE_READONLY (expr);
506 : 21230 : TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr);
507 : 21230 : TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
508 : : }
509 : 157844591 : switch (code)
510 : : {
511 : : case FIX_TRUNC_EXPR:
512 : : case FLOAT_EXPR:
513 : : CASE_CONVERT:
514 : : /* Don't warn about explicit conversions. We will already
515 : : have warned about suspect implicit conversions. */
516 : : break;
517 : :
518 : 131884112 : default:
519 : 131884112 : if (TREE_OVERFLOW_P (ret) && !TREE_OVERFLOW_P (op0))
520 : 0 : overflow_warning (EXPR_LOCATION (expr), ret, op0);
521 : : break;
522 : : }
523 : 157844591 : goto out;
524 : :
525 : 433779 : case TRUTH_ANDIF_EXPR:
526 : 433779 : case TRUTH_ORIF_EXPR:
527 : : /* Binary operations not necessarily evaluating both
528 : : arguments. */
529 : 433779 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
530 : 433779 : orig_op1 = op1 = TREE_OPERAND (expr, 1);
531 : 433779 : op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self,
532 : : for_int_const, false);
533 : 867558 : STRIP_TYPE_NOPS (op0);
534 : :
535 : 867558 : unused_p = (op0 == (code == TRUTH_ANDIF_EXPR
536 : 433779 : ? truthvalue_false_node
537 : : : truthvalue_true_node));
538 : 433779 : c_disable_warnings (unused_p);
539 : 433779 : op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self,
540 : : for_int_const, false);
541 : 867558 : STRIP_TYPE_NOPS (op1);
542 : 433779 : c_enable_warnings (unused_p);
543 : :
544 : 433779 : if (for_int_const
545 : 50 : && (TREE_CODE (op0) != INTEGER_CST
546 : : /* Require OP1 be an INTEGER_CST only if it's evaluated. */
547 : 36 : || (!unused_p && TREE_CODE (op1) != INTEGER_CST)))
548 : 40 : goto out;
549 : :
550 : 433739 : if (op0 != orig_op0 || op1 != orig_op1 || in_init)
551 : 424644 : ret = in_init
552 : 424644 : ? fold_build2_initializer_loc (loc, code, TREE_TYPE (expr), op0, op1)
553 : 424629 : : fold_build2_loc (loc, code, TREE_TYPE (expr), op0, op1);
554 : : else
555 : 9095 : ret = fold (expr);
556 : 433739 : *maybe_const_operands &= op0_const;
557 : 433739 : *maybe_const_itself &= op0_const_self;
558 : 762704 : if (!(flag_isoc99
559 : 430238 : && op0_const
560 : 328965 : && op0_const_self
561 : : && (code == TRUTH_ANDIF_EXPR
562 : 119317 : ? op0 == truthvalue_false_node
563 : 209648 : : op0 == truthvalue_true_node)))
564 : 424204 : *maybe_const_operands &= op1_const;
565 : 765455 : if (!(op0_const
566 : 331716 : && op0_const_self
567 : : && (code == TRUTH_ANDIF_EXPR
568 : 119596 : ? op0 == truthvalue_false_node
569 : 212120 : : op0 == truthvalue_true_node)))
570 : 424186 : *maybe_const_itself &= op1_const_self;
571 : 433739 : goto out;
572 : :
573 : 236092 : case COND_EXPR:
574 : 236092 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
575 : 236092 : orig_op1 = op1 = TREE_OPERAND (expr, 1);
576 : 236092 : orig_op2 = op2 = TREE_OPERAND (expr, 2);
577 : 236092 : op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self,
578 : : for_int_const, false);
579 : :
580 : 472184 : STRIP_TYPE_NOPS (op0);
581 : 236092 : c_disable_warnings (op0 == truthvalue_false_node);
582 : 236092 : op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self,
583 : : for_int_const, false);
584 : 472184 : STRIP_TYPE_NOPS (op1);
585 : 236092 : c_enable_warnings (op0 == truthvalue_false_node);
586 : :
587 : 236092 : c_disable_warnings (op0 == truthvalue_true_node);
588 : 236092 : op2 = c_fully_fold_internal (op2, in_init, &op2_const, &op2_const_self,
589 : : for_int_const, false);
590 : 472190 : STRIP_TYPE_NOPS (op2);
591 : 236092 : c_enable_warnings (op0 == truthvalue_true_node);
592 : :
593 : 236092 : if (for_int_const
594 : 76 : && (TREE_CODE (op0) != INTEGER_CST
595 : : /* Only the evaluated operand must be an INTEGER_CST. */
596 : 41 : || (op0 == truthvalue_true_node
597 : 14 : ? TREE_CODE (op1) != INTEGER_CST
598 : 27 : : TREE_CODE (op2) != INTEGER_CST)))
599 : 62 : goto out;
600 : :
601 : 236030 : if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2)
602 : 187304 : ret = fold_build3_loc (loc, code, TREE_TYPE (expr), op0, op1, op2);
603 : : else
604 : 48726 : ret = fold (expr);
605 : 236030 : *maybe_const_operands &= op0_const;
606 : 236030 : *maybe_const_itself &= op0_const_self;
607 : 236030 : if (!(flag_isoc99
608 : 234721 : && op0_const
609 : 168396 : && op0_const_self
610 : 168396 : && op0 == truthvalue_false_node))
611 : 221486 : *maybe_const_operands &= op1_const;
612 : 236030 : if (!(op0_const
613 : 169501 : && op0_const_self
614 : 169501 : && op0 == truthvalue_false_node))
615 : 221138 : *maybe_const_itself &= op1_const_self;
616 : 236030 : if (!(flag_isoc99
617 : 234721 : && op0_const
618 : 168396 : && op0_const_self
619 : 168396 : && op0 == truthvalue_true_node))
620 : 192437 : *maybe_const_operands &= op2_const;
621 : 236030 : if (!(op0_const
622 : 169501 : && op0_const_self
623 : 169501 : && op0 == truthvalue_true_node))
624 : 192319 : *maybe_const_itself &= op2_const_self;
625 : 236030 : goto out;
626 : :
627 : 97781 : case VEC_COND_EXPR:
628 : 97781 : orig_op0 = op0 = TREE_OPERAND (expr, 0);
629 : 97781 : orig_op1 = op1 = TREE_OPERAND (expr, 1);
630 : 97781 : orig_op2 = op2 = TREE_OPERAND (expr, 2);
631 : 97781 : op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
632 : : maybe_const_itself, for_int_const, false);
633 : 195562 : STRIP_TYPE_NOPS (op0);
634 : 97781 : op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
635 : : maybe_const_itself, for_int_const, false);
636 : 195562 : STRIP_TYPE_NOPS (op1);
637 : 97781 : op2 = c_fully_fold_internal (op2, in_init, maybe_const_operands,
638 : : maybe_const_itself, for_int_const, false);
639 : 195562 : STRIP_TYPE_NOPS (op2);
640 : :
641 : 97781 : if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2)
642 : 522 : ret = fold_build3_loc (loc, code, TREE_TYPE (expr), op0, op1, op2);
643 : : else
644 : 97259 : ret = fold (expr);
645 : 97781 : goto out;
646 : :
647 : 0 : case EXCESS_PRECISION_EXPR:
648 : : /* Each case where an operand with excess precision may be
649 : : encountered must remove the EXCESS_PRECISION_EXPR around
650 : : inner operands and possibly put one around the whole
651 : : expression or possibly convert to the semantic type (which
652 : : c_fully_fold does); we cannot tell at this stage which is
653 : : appropriate in any particular case. */
654 : 0 : gcc_unreachable ();
655 : :
656 : 175120 : case SAVE_EXPR:
657 : : /* Make sure to fold the contents of a SAVE_EXPR exactly once. */
658 : 175120 : op0 = TREE_OPERAND (expr, 0);
659 : 175120 : if (!SAVE_EXPR_FOLDED_P (expr))
660 : : {
661 : 83539 : op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
662 : : maybe_const_itself, for_int_const,
663 : : false);
664 : 83539 : TREE_OPERAND (expr, 0) = op0;
665 : 83539 : SAVE_EXPR_FOLDED_P (expr) = true;
666 : : }
667 : : /* Return the SAVE_EXPR operand if it is invariant. */
668 : 175120 : if (tree_invariant_p (op0))
669 : 3344 : ret = op0;
670 : 175120 : goto out;
671 : :
672 : 8153 : default:
673 : : /* Various codes may appear through folding built-in functions
674 : : and their arguments. */
675 : 8153 : goto out;
676 : : }
677 : :
678 : 226161558 : out:
679 : : /* Some folding may introduce NON_LVALUE_EXPRs; all lvalue checks
680 : : have been done by this point, so remove them again. */
681 : 226161558 : nowarning |= warning_suppressed_p (ret, OPT_Woverflow);
682 : 226302694 : STRIP_TYPE_NOPS (ret);
683 : 226161558 : if (nowarning && !warning_suppressed_p (ret, OPT_Woverflow))
684 : : {
685 : 10614 : if (!CAN_HAVE_LOCATION_P (ret))
686 : 755 : ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
687 : 10614 : suppress_warning (ret, OPT_Woverflow);
688 : : }
689 : 226161558 : if (ret != expr)
690 : : {
691 : 12850682 : protected_set_expr_location (ret, loc);
692 : 12850682 : if (IS_EXPR_CODE_CLASS (kind))
693 : 12850682 : set_source_range (ret, old_range.m_start, old_range.m_finish);
694 : : }
695 : : return ret;
696 : : }
697 : :
698 : : /* Fold X for consideration by one of the warning functions when checking
699 : : whether an expression has a constant value. */
700 : :
701 : : tree
702 : 113046045 : fold_for_warn (tree x)
703 : : {
704 : : /* The C front-end has already folded X appropriately. */
705 : 113046045 : return x;
706 : : }
|