comparison gcc/c/c-fold.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 /* Support for fully folding sub-trees of an expression for C compiler. 1 /* Support for fully folding sub-trees of an expression for C compiler.
2 Copyright (C) 1992-2017 Free Software Foundation, Inc. 2 Copyright (C) 1992-2018 Free Software Foundation, Inc.
3 3
4 This file is part of GCC. 4 This file is part of GCC.
5 5
6 GCC is free software; you can redistribute it and/or modify it under 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 7 the terms of the GNU General Public License as published by the Free
25 #include "bitmap.h" 25 #include "bitmap.h"
26 #include "c-tree.h" 26 #include "c-tree.h"
27 #include "intl.h" 27 #include "intl.h"
28 #include "gimplify.h" 28 #include "gimplify.h"
29 29
30 static tree c_fully_fold_internal (tree expr, bool, bool *, bool *, bool); 30 static tree c_fully_fold_internal (tree expr, bool, bool *, bool *, bool,
31 bool);
31 32
32 /* If DISABLE is true, stop issuing warnings. This is used when 33 /* If DISABLE is true, stop issuing warnings. This is used when
33 parsing code that we know will not be executed. This function may 34 parsing code that we know will not be executed. This function may
34 be called multiple times, and works as a stack. */ 35 be called multiple times, and works as a stack. */
35 36
51 if (enable) 52 if (enable)
52 { 53 {
53 --c_inhibit_evaluation_warnings; 54 --c_inhibit_evaluation_warnings;
54 fold_undefer_and_ignore_overflow_warnings (); 55 fold_undefer_and_ignore_overflow_warnings ();
55 } 56 }
57 }
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 c_fold_array_ref (tree type, tree ary, tree index)
64 {
65 if (TREE_CODE (ary) != STRING_CST
66 || TREE_CODE (index) != INTEGER_CST
67 || TREE_OVERFLOW (index)
68 || TREE_CODE (TREE_TYPE (ary)) != ARRAY_TYPE
69 || !tree_fits_uhwi_p (index))
70 return NULL_TREE;
71
72 tree elem_type = TREE_TYPE (TREE_TYPE (ary));
73 unsigned elem_nchars = (TYPE_PRECISION (elem_type)
74 / TYPE_PRECISION (char_type_node));
75 unsigned len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
76 tree nelts = array_type_nelts (TREE_TYPE (ary));
77 bool dummy1 = true, dummy2 = true;
78 nelts = c_fully_fold_internal (nelts, true, &dummy1, &dummy2, false, false);
79 unsigned HOST_WIDE_INT i = tree_to_uhwi (index);
80 if (!tree_int_cst_le (index, nelts)
81 || i >= len
82 || i + elem_nchars > len)
83 return NULL_TREE;
84
85 if (elem_nchars == 1)
86 return build_int_cst (type, TREE_STRING_POINTER (ary)[i]);
87
88 const unsigned char *ptr
89 = ((const unsigned char *)TREE_STRING_POINTER (ary) + i * elem_nchars);
90 return native_interpret_expr (type, ptr, elem_nchars);
56 } 91 }
57 92
58 /* Fully fold EXPR, an expression that was not folded (beyond integer 93 /* Fully fold EXPR, an expression that was not folded (beyond integer
59 constant expressions and null pointer constants) when being built 94 constant expressions and null pointer constants) when being built
60 up. If IN_INIT, this is in a static initializer and certain 95 up. If IN_INIT, this is in a static initializer and certain
66 evaluated arithmetic overflow. (*MAYBE_CONST should typically be 101 evaluated arithmetic overflow. (*MAYBE_CONST should typically be
67 set to true by callers before calling this function.) Return the 102 set to true by callers before calling this function.) Return the
68 folded expression. Function arguments have already been folded 103 folded expression. Function arguments have already been folded
69 before calling this function, as have the contents of SAVE_EXPR, 104 before calling this function, as have the contents of SAVE_EXPR,
70 TARGET_EXPR, BIND_EXPR, VA_ARG_EXPR, OBJ_TYPE_REF and 105 TARGET_EXPR, BIND_EXPR, VA_ARG_EXPR, OBJ_TYPE_REF and
71 C_MAYBE_CONST_EXPR. */ 106 C_MAYBE_CONST_EXPR. LVAL is true if it should be treated as an
107 lvalue. */
72 108
73 tree 109 tree
74 c_fully_fold (tree expr, bool in_init, bool *maybe_const) 110 c_fully_fold (tree expr, bool in_init, bool *maybe_const, bool lval)
75 { 111 {
76 tree ret; 112 tree ret;
77 tree eptype = NULL_TREE; 113 tree eptype = NULL_TREE;
78 bool dummy = true; 114 bool dummy = true;
79 bool maybe_const_itself = true; 115 bool maybe_const_itself = true;
85 { 121 {
86 eptype = TREE_TYPE (expr); 122 eptype = TREE_TYPE (expr);
87 expr = TREE_OPERAND (expr, 0); 123 expr = TREE_OPERAND (expr, 0);
88 } 124 }
89 ret = c_fully_fold_internal (expr, in_init, maybe_const, 125 ret = c_fully_fold_internal (expr, in_init, maybe_const,
90 &maybe_const_itself, false); 126 &maybe_const_itself, false, lval);
91 if (eptype) 127 if (eptype)
92 ret = fold_convert_loc (loc, eptype, ret); 128 ret = fold_convert_loc (loc, eptype, ret);
93 *maybe_const &= maybe_const_itself; 129 *maybe_const &= maybe_const_itself;
94 return ret; 130 return ret;
95 } 131 }
100 arithmetic overflow (for C90, *MAYBE_CONST_OPERANDS is carried from 136 arithmetic overflow (for C90, *MAYBE_CONST_OPERANDS is carried from
101 both evaluated and unevaluated subexpressions while 137 both evaluated and unevaluated subexpressions while
102 *MAYBE_CONST_ITSELF is carried from only evaluated 138 *MAYBE_CONST_ITSELF is carried from only evaluated
103 subexpressions). FOR_INT_CONST indicates if EXPR is an expression 139 subexpressions). FOR_INT_CONST indicates if EXPR is an expression
104 with integer constant operands, and if any of the operands doesn't 140 with integer constant operands, and if any of the operands doesn't
105 get folded to an integer constant, don't fold the expression itself. */ 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. */
106 144
107 static tree 145 static tree
108 c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, 146 c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
109 bool *maybe_const_itself, bool for_int_const) 147 bool *maybe_const_itself, bool for_int_const, bool lval)
110 { 148 {
111 tree ret = expr; 149 tree ret = expr;
112 enum tree_code code = TREE_CODE (expr); 150 enum tree_code code = TREE_CODE (expr);
113 enum tree_code_class kind = TREE_CODE_CLASS (code); 151 enum tree_code_class kind = TREE_CODE_CLASS (code);
114 location_t loc = EXPR_LOCATION (expr); 152 location_t loc = EXPR_LOCATION (expr);
116 tree orig_op0, orig_op1, orig_op2; 154 tree orig_op0, orig_op1, orig_op2;
117 bool op0_const = true, op1_const = true, op2_const = true; 155 bool op0_const = true, op1_const = true, op2_const = true;
118 bool op0_const_self = true, op1_const_self = true, op2_const_self = true; 156 bool op0_const_self = true, op1_const_self = true, op2_const_self = true;
119 bool nowarning = TREE_NO_WARNING (expr); 157 bool nowarning = TREE_NO_WARNING (expr);
120 bool unused_p; 158 bool unused_p;
159 bool op0_lval = false;
121 source_range old_range; 160 source_range old_range;
122 161
123 /* Constants, declarations, statements, errors, and anything else not 162 /* Constants, declarations, statements, errors, and anything else not
124 counted as an expression cannot usefully be folded further at this 163 counted as an expression cannot usefully be folded further at this
125 point. */ 164 point. */
126 if (!IS_EXPR_CODE_CLASS (kind) 165 if (!IS_EXPR_CODE_CLASS (kind) || kind == tcc_statement)
127 || kind == tcc_statement) 166 {
128 return expr; 167 /* Except for variables which we can optimize to its initializer. */
168 if (VAR_P (expr) && !lval && (optimize || in_init))
169 {
170 if (in_init)
171 ret = decl_constant_value_1 (expr, true);
172 else
173 {
174 ret = decl_constant_value (expr);
175 if (ret != expr
176 && (TYPE_MODE (TREE_TYPE (ret)) == BLKmode
177 || 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 if (ret != expr && TREE_STATIC (expr))
184 ret = unshare_expr (ret);
185 return ret;
186 }
187 return expr;
188 }
129 189
130 if (IS_EXPR_CODE_CLASS (kind)) 190 if (IS_EXPR_CODE_CLASS (kind))
131 old_range = EXPR_LOCATION_RANGE (expr); 191 old_range = EXPR_LOCATION_RANGE (expr);
132 192
133 /* Operands of variable-length expressions (function calls) have 193 /* Operands of variable-length expressions (function calls) have
148 *maybe_const_operands = false; 208 *maybe_const_operands = false;
149 if (C_MAYBE_CONST_EXPR_INT_OPERANDS (expr)) 209 if (C_MAYBE_CONST_EXPR_INT_OPERANDS (expr))
150 { 210 {
151 *maybe_const_itself = false; 211 *maybe_const_itself = false;
152 inner = c_fully_fold_internal (inner, in_init, maybe_const_operands, 212 inner = c_fully_fold_internal (inner, in_init, maybe_const_operands,
153 maybe_const_itself, true); 213 maybe_const_itself, true, lval);
154 } 214 }
155 if (pre && !in_init) 215 if (pre && !in_init)
156 ret = build2 (COMPOUND_EXPR, TREE_TYPE (expr), pre, inner); 216 ret = build2 (COMPOUND_EXPR, TREE_TYPE (expr), pre, inner);
157 else 217 else
158 ret = inner; 218 ret = inner;
199 case COMPONENT_REF: 259 case COMPONENT_REF:
200 orig_op0 = op0 = TREE_OPERAND (expr, 0); 260 orig_op0 = op0 = TREE_OPERAND (expr, 0);
201 op1 = TREE_OPERAND (expr, 1); 261 op1 = TREE_OPERAND (expr, 1);
202 op2 = TREE_OPERAND (expr, 2); 262 op2 = TREE_OPERAND (expr, 2);
203 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, 263 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
204 maybe_const_itself, for_int_const); 264 maybe_const_itself, for_int_const, lval);
205 STRIP_TYPE_NOPS (op0); 265 STRIP_TYPE_NOPS (op0);
206 if (op0 != orig_op0) 266 if (op0 != orig_op0)
207 ret = build3 (COMPONENT_REF, TREE_TYPE (expr), op0, op1, op2); 267 ret = build3 (COMPONENT_REF, TREE_TYPE (expr), op0, op1, op2);
208 if (ret != expr) 268 if (ret != expr)
209 { 269 {
210 TREE_READONLY (ret) = TREE_READONLY (expr); 270 TREE_READONLY (ret) = TREE_READONLY (expr);
211 TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr); 271 TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
212 } 272 }
273 if (!lval)
274 ret = fold (ret);
213 goto out; 275 goto out;
214 276
215 case ARRAY_REF: 277 case ARRAY_REF:
216 orig_op0 = op0 = TREE_OPERAND (expr, 0); 278 orig_op0 = op0 = TREE_OPERAND (expr, 0);
217 orig_op1 = op1 = TREE_OPERAND (expr, 1); 279 orig_op1 = op1 = TREE_OPERAND (expr, 1);
218 op2 = TREE_OPERAND (expr, 2); 280 op2 = TREE_OPERAND (expr, 2);
219 op3 = TREE_OPERAND (expr, 3); 281 op3 = TREE_OPERAND (expr, 3);
220 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, 282 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
221 maybe_const_itself, for_int_const); 283 maybe_const_itself, for_int_const, lval);
222 STRIP_TYPE_NOPS (op0); 284 STRIP_TYPE_NOPS (op0);
223 op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands, 285 op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
224 maybe_const_itself, for_int_const); 286 maybe_const_itself, for_int_const, false);
225 STRIP_TYPE_NOPS (op1); 287 STRIP_TYPE_NOPS (op1);
226 op1 = decl_constant_value_for_optimization (op1); 288 /* Fold "foo"[2] in initializers. */
289 if (!lval && in_init)
290 {
291 ret = c_fold_array_ref (TREE_TYPE (expr), op0, op1);
292 if (ret)
293 goto out;
294 ret = expr;
295 }
227 if (op0 != orig_op0 || op1 != orig_op1) 296 if (op0 != orig_op0 || op1 != orig_op1)
228 ret = build4 (ARRAY_REF, TREE_TYPE (expr), op0, op1, op2, op3); 297 ret = build4 (ARRAY_REF, TREE_TYPE (expr), op0, op1, op2, op3);
229 if (ret != expr) 298 if (ret != expr)
230 { 299 {
231 TREE_READONLY (ret) = TREE_READONLY (expr); 300 TREE_READONLY (ret) = TREE_READONLY (expr);
232 TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr); 301 TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr);
233 TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr); 302 TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
234 } 303 }
235 ret = fold (ret); 304 if (!lval)
236 goto out; 305 ret = fold (ret);
237 306 goto out;
238 case COMPOUND_EXPR: 307
239 case MODIFY_EXPR: 308 case MODIFY_EXPR:
240 case PREDECREMENT_EXPR: 309 case PREDECREMENT_EXPR:
241 case PREINCREMENT_EXPR: 310 case PREINCREMENT_EXPR:
242 case POSTDECREMENT_EXPR: 311 case POSTDECREMENT_EXPR:
243 case POSTINCREMENT_EXPR: 312 case POSTINCREMENT_EXPR:
313 op0_lval = true;
314 /* FALLTHRU */
315 case COMPOUND_EXPR:
244 case PLUS_EXPR: 316 case PLUS_EXPR:
245 case MINUS_EXPR: 317 case MINUS_EXPR:
246 case MULT_EXPR: 318 case MULT_EXPR:
247 case POINTER_PLUS_EXPR: 319 case POINTER_PLUS_EXPR:
320 case POINTER_DIFF_EXPR:
248 case TRUNC_DIV_EXPR: 321 case TRUNC_DIV_EXPR:
249 case CEIL_DIV_EXPR: 322 case CEIL_DIV_EXPR:
250 case FLOOR_DIV_EXPR: 323 case FLOOR_DIV_EXPR:
251 case TRUNC_MOD_EXPR: 324 case TRUNC_MOD_EXPR:
252 case RDIV_EXPR: 325 case RDIV_EXPR:
276 /* Binary operations evaluating both arguments (increment and 349 /* Binary operations evaluating both arguments (increment and
277 decrement are binary internally in GCC). */ 350 decrement are binary internally in GCC). */
278 orig_op0 = op0 = TREE_OPERAND (expr, 0); 351 orig_op0 = op0 = TREE_OPERAND (expr, 0);
279 orig_op1 = op1 = TREE_OPERAND (expr, 1); 352 orig_op1 = op1 = TREE_OPERAND (expr, 1);
280 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, 353 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
281 maybe_const_itself, for_int_const); 354 maybe_const_itself, for_int_const,
355 op0_lval);
282 STRIP_TYPE_NOPS (op0); 356 STRIP_TYPE_NOPS (op0);
283 if (code != MODIFY_EXPR
284 && code != PREDECREMENT_EXPR
285 && code != PREINCREMENT_EXPR
286 && code != POSTDECREMENT_EXPR
287 && code != POSTINCREMENT_EXPR)
288 op0 = decl_constant_value_for_optimization (op0);
289 /* The RHS of a MODIFY_EXPR was fully folded when building that 357 /* The RHS of a MODIFY_EXPR was fully folded when building that
290 expression for the sake of conversion warnings. */ 358 expression for the sake of conversion warnings. */
291 if (code != MODIFY_EXPR) 359 if (code != MODIFY_EXPR)
292 op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands, 360 op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
293 maybe_const_itself, for_int_const); 361 maybe_const_itself, for_int_const, false);
294 STRIP_TYPE_NOPS (op1); 362 STRIP_TYPE_NOPS (op1);
295 op1 = decl_constant_value_for_optimization (op1);
296 363
297 if (for_int_const && (TREE_CODE (op0) != INTEGER_CST 364 if (for_int_const && (TREE_CODE (op0) != INTEGER_CST
298 || TREE_CODE (op1) != INTEGER_CST)) 365 || TREE_CODE (op1) != INTEGER_CST))
299 goto out; 366 goto out;
300 367
368 || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE) 435 || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE)
369 && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE) 436 && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE)
370 warn_for_div_by_zero (loc, op1); 437 warn_for_div_by_zero (loc, op1);
371 goto out; 438 goto out;
372 439
440 case ADDR_EXPR:
441 op0_lval = true;
442 goto unary;
443 case REALPART_EXPR:
444 case IMAGPART_EXPR:
445 case VIEW_CONVERT_EXPR:
446 op0_lval = lval;
447 /* FALLTHRU */
373 case INDIRECT_REF: 448 case INDIRECT_REF:
374 case FIX_TRUNC_EXPR: 449 case FIX_TRUNC_EXPR:
375 case FLOAT_EXPR: 450 case FLOAT_EXPR:
376 CASE_CONVERT: 451 CASE_CONVERT:
377 case ADDR_SPACE_CONVERT_EXPR: 452 case ADDR_SPACE_CONVERT_EXPR:
378 case VIEW_CONVERT_EXPR:
379 case NON_LVALUE_EXPR: 453 case NON_LVALUE_EXPR:
380 case NEGATE_EXPR: 454 case NEGATE_EXPR:
381 case BIT_NOT_EXPR: 455 case BIT_NOT_EXPR:
382 case TRUTH_NOT_EXPR: 456 case TRUTH_NOT_EXPR:
383 case ADDR_EXPR:
384 case CONJ_EXPR: 457 case CONJ_EXPR:
385 case REALPART_EXPR: 458 unary:
386 case IMAGPART_EXPR:
387 /* Unary operations. */ 459 /* Unary operations. */
388 orig_op0 = op0 = TREE_OPERAND (expr, 0); 460 orig_op0 = op0 = TREE_OPERAND (expr, 0);
389 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, 461 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
390 maybe_const_itself, for_int_const); 462 maybe_const_itself, for_int_const,
463 op0_lval);
391 STRIP_TYPE_NOPS (op0); 464 STRIP_TYPE_NOPS (op0);
392 if (code != ADDR_EXPR && code != REALPART_EXPR && code != IMAGPART_EXPR)
393 op0 = decl_constant_value_for_optimization (op0);
394 465
395 if (for_int_const && TREE_CODE (op0) != INTEGER_CST) 466 if (for_int_const && TREE_CODE (op0) != INTEGER_CST)
396 goto out; 467 goto out;
397 468
398 /* ??? Cope with user tricks that amount to offsetof. The middle-end is 469 /* ??? Cope with user tricks that amount to offsetof. The middle-end is
400 if (op0 != orig_op0 471 if (op0 != orig_op0
401 && code == ADDR_EXPR 472 && code == ADDR_EXPR
402 && (op1 = get_base_address (op0)) != NULL_TREE 473 && (op1 = get_base_address (op0)) != NULL_TREE
403 && INDIRECT_REF_P (op1) 474 && INDIRECT_REF_P (op1)
404 && TREE_CONSTANT (TREE_OPERAND (op1, 0))) 475 && TREE_CONSTANT (TREE_OPERAND (op1, 0)))
405 ret = fold_convert_loc (loc, TREE_TYPE (expr), fold_offsetof_1 (op0)); 476 ret = fold_offsetof (op0, TREE_TYPE (expr));
406 else if (op0 != orig_op0 || in_init) 477 else if (op0 != orig_op0 || in_init)
407 ret = in_init 478 ret = in_init
408 ? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0) 479 ? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0)
409 : fold_build1_loc (loc, code, TREE_TYPE (expr), op0); 480 : fold_build1_loc (loc, code, TREE_TYPE (expr), op0);
410 else 481 else
438 /* Binary operations not necessarily evaluating both 509 /* Binary operations not necessarily evaluating both
439 arguments. */ 510 arguments. */
440 orig_op0 = op0 = TREE_OPERAND (expr, 0); 511 orig_op0 = op0 = TREE_OPERAND (expr, 0);
441 orig_op1 = op1 = TREE_OPERAND (expr, 1); 512 orig_op1 = op1 = TREE_OPERAND (expr, 1);
442 op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self, 513 op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self,
443 for_int_const); 514 for_int_const, false);
444 STRIP_TYPE_NOPS (op0); 515 STRIP_TYPE_NOPS (op0);
445 516
446 unused_p = (op0 == (code == TRUTH_ANDIF_EXPR 517 unused_p = (op0 == (code == TRUTH_ANDIF_EXPR
447 ? truthvalue_false_node 518 ? truthvalue_false_node
448 : truthvalue_true_node)); 519 : truthvalue_true_node));
449 c_disable_warnings (unused_p); 520 c_disable_warnings (unused_p);
450 op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self, 521 op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self,
451 for_int_const); 522 for_int_const, false);
452 STRIP_TYPE_NOPS (op1); 523 STRIP_TYPE_NOPS (op1);
453 c_enable_warnings (unused_p); 524 c_enable_warnings (unused_p);
454 525
455 if (for_int_const 526 if (for_int_const
456 && (TREE_CODE (op0) != INTEGER_CST 527 && (TREE_CODE (op0) != INTEGER_CST
484 case COND_EXPR: 555 case COND_EXPR:
485 orig_op0 = op0 = TREE_OPERAND (expr, 0); 556 orig_op0 = op0 = TREE_OPERAND (expr, 0);
486 orig_op1 = op1 = TREE_OPERAND (expr, 1); 557 orig_op1 = op1 = TREE_OPERAND (expr, 1);
487 orig_op2 = op2 = TREE_OPERAND (expr, 2); 558 orig_op2 = op2 = TREE_OPERAND (expr, 2);
488 op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self, 559 op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self,
489 for_int_const); 560 for_int_const, false);
490 561
491 STRIP_TYPE_NOPS (op0); 562 STRIP_TYPE_NOPS (op0);
492 c_disable_warnings (op0 == truthvalue_false_node); 563 c_disable_warnings (op0 == truthvalue_false_node);
493 op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self, 564 op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self,
494 for_int_const); 565 for_int_const, false);
495 STRIP_TYPE_NOPS (op1); 566 STRIP_TYPE_NOPS (op1);
496 c_enable_warnings (op0 == truthvalue_false_node); 567 c_enable_warnings (op0 == truthvalue_false_node);
497 568
498 c_disable_warnings (op0 == truthvalue_true_node); 569 c_disable_warnings (op0 == truthvalue_true_node);
499 op2 = c_fully_fold_internal (op2, in_init, &op2_const, &op2_const_self, 570 op2 = c_fully_fold_internal (op2, in_init, &op2_const, &op2_const_self,
500 for_int_const); 571 for_int_const, false);
501 STRIP_TYPE_NOPS (op2); 572 STRIP_TYPE_NOPS (op2);
502 c_enable_warnings (op0 == truthvalue_true_node); 573 c_enable_warnings (op0 == truthvalue_true_node);
503 574
504 if (for_int_const 575 if (for_int_const
505 && (TREE_CODE (op0) != INTEGER_CST 576 && (TREE_CODE (op0) != INTEGER_CST
538 case VEC_COND_EXPR: 609 case VEC_COND_EXPR:
539 orig_op0 = op0 = TREE_OPERAND (expr, 0); 610 orig_op0 = op0 = TREE_OPERAND (expr, 0);
540 orig_op1 = op1 = TREE_OPERAND (expr, 1); 611 orig_op1 = op1 = TREE_OPERAND (expr, 1);
541 orig_op2 = op2 = TREE_OPERAND (expr, 2); 612 orig_op2 = op2 = TREE_OPERAND (expr, 2);
542 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, 613 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
543 maybe_const_itself, for_int_const); 614 maybe_const_itself, for_int_const, false);
544 STRIP_TYPE_NOPS (op0); 615 STRIP_TYPE_NOPS (op0);
545 op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands, 616 op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
546 maybe_const_itself, for_int_const); 617 maybe_const_itself, for_int_const, false);
547 STRIP_TYPE_NOPS (op1); 618 STRIP_TYPE_NOPS (op1);
548 op2 = c_fully_fold_internal (op2, in_init, maybe_const_operands, 619 op2 = c_fully_fold_internal (op2, in_init, maybe_const_operands,
549 maybe_const_itself, for_int_const); 620 maybe_const_itself, for_int_const, false);
550 STRIP_TYPE_NOPS (op2); 621 STRIP_TYPE_NOPS (op2);
551 622
552 if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2) 623 if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2)
553 ret = fold_build3_loc (loc, code, TREE_TYPE (expr), op0, op1, op2); 624 ret = fold_build3_loc (loc, code, TREE_TYPE (expr), op0, op1, op2);
554 else 625 else
568 /* Make sure to fold the contents of a SAVE_EXPR exactly once. */ 639 /* Make sure to fold the contents of a SAVE_EXPR exactly once. */
569 op0 = TREE_OPERAND (expr, 0); 640 op0 = TREE_OPERAND (expr, 0);
570 if (!SAVE_EXPR_FOLDED_P (expr)) 641 if (!SAVE_EXPR_FOLDED_P (expr))
571 { 642 {
572 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, 643 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
573 maybe_const_itself, for_int_const); 644 maybe_const_itself, for_int_const,
645 false);
574 TREE_OPERAND (expr, 0) = op0; 646 TREE_OPERAND (expr, 0) = op0;
575 SAVE_EXPR_FOLDED_P (expr) = true; 647 SAVE_EXPR_FOLDED_P (expr) = true;
576 } 648 }
577 /* Return the SAVE_EXPR operand if it is invariant. */ 649 /* Return the SAVE_EXPR operand if it is invariant. */
578 if (tree_invariant_p (op0)) 650 if (tree_invariant_p (op0))
603 set_source_range (ret, old_range.m_start, old_range.m_finish); 675 set_source_range (ret, old_range.m_start, old_range.m_finish);
604 } 676 }
605 return ret; 677 return ret;
606 } 678 }
607 679
608 /* If not optimizing, EXP is not a VAR_DECL, or EXP has array type, 680 /* Fold X for consideration by one of the warning functions when checking
609 return EXP. Otherwise, return either EXP or its known constant 681 whether an expression has a constant value. */
610 value (if it has one), but return EXP if EXP has mode BLKmode. ???
611 Is the BLKmode test appropriate? */
612 682
613 tree 683 tree
614 decl_constant_value_for_optimization (tree exp) 684 fold_for_warn (tree x)
615 { 685 {
616 tree ret; 686 /* The C front-end has already folded X appropriately. */
617 687 return x;
618 if (!optimize
619 || !VAR_P (exp)
620 || TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
621 || DECL_MODE (exp) == BLKmode)
622 return exp;
623
624 ret = decl_constant_value (exp);
625 /* Avoid unwanted tree sharing between the initializer and current
626 function's body where the tree can be modified e.g. by the
627 gimplifier. */
628 if (ret != exp && TREE_STATIC (exp))
629 ret = unshare_expr (ret);
630 return ret;
631 } 688 }