op2 = TREE_OPERAND (expr, 2);
op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
maybe_const_itself);
+ STRIP_TYPE_NOPS (op0);
if (op0 != orig_op0)
ret = build3 (COMPONENT_REF, TREE_TYPE (expr), op0, op1, op2);
if (ret != expr)
op3 = TREE_OPERAND (expr, 3);
op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
maybe_const_itself);
+ STRIP_TYPE_NOPS (op0);
op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
maybe_const_itself);
+ STRIP_TYPE_NOPS (op1);
op1 = decl_constant_value_for_optimization (op1);
if (op0 != orig_op0 || op1 != orig_op1)
ret = build4 (ARRAY_REF, TREE_TYPE (expr), op0, op1, op2, op3);
orig_op1 = op1 = TREE_OPERAND (expr, 1);
op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
maybe_const_itself);
+ STRIP_TYPE_NOPS (op0);
if (code != MODIFY_EXPR
&& code != PREDECREMENT_EXPR
&& code != PREINCREMENT_EXPR
if (code != MODIFY_EXPR)
op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
maybe_const_itself);
+ STRIP_TYPE_NOPS (op1);
op1 = decl_constant_value_for_optimization (op1);
if (op0 != orig_op0 || op1 != orig_op1 || in_init)
ret = in_init
orig_op0 = op0 = TREE_OPERAND (expr, 0);
op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
maybe_const_itself);
+ STRIP_TYPE_NOPS (op0);
if (code != ADDR_EXPR && code != REALPART_EXPR && code != IMAGPART_EXPR)
op0 = decl_constant_value_for_optimization (op0);
if (op0 != orig_op0 || in_init)
orig_op0 = op0 = TREE_OPERAND (expr, 0);
orig_op1 = op1 = TREE_OPERAND (expr, 1);
op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self);
+ STRIP_TYPE_NOPS (op0);
unused_p = (op0 == (code == TRUTH_ANDIF_EXPR
? truthvalue_false_node
: truthvalue_true_node));
c_inhibit_evaluation_warnings += unused_p;
op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self);
+ STRIP_TYPE_NOPS (op1);
c_inhibit_evaluation_warnings -= unused_p;
if (op0 != orig_op0 || op1 != orig_op1 || in_init)
orig_op2 = op2 = TREE_OPERAND (expr, 2);
op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self);
+ STRIP_TYPE_NOPS (op0);
c_inhibit_evaluation_warnings += (op0 == truthvalue_false_node);
op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self);
+ STRIP_TYPE_NOPS (op1);
c_inhibit_evaluation_warnings -= (op0 == truthvalue_false_node);
c_inhibit_evaluation_warnings += (op0 == truthvalue_true_node);
op2 = c_fully_fold_internal (op2, in_init, &op2_const, &op2_const_self);
+ STRIP_TYPE_NOPS (op2);
c_inhibit_evaluation_warnings -= (op0 == truthvalue_true_node);
if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2)
return ret;
}
\f
+/* Wrap a C_MAYBE_CONST_EXPR around an expression that is fully folded
+ and if NON_CONST is known not to be permitted in an evaluated part
+ of a constant expression. */
+
+tree
+c_wrap_maybe_const (tree expr, bool non_const)
+{
+ bool nowarning = TREE_NO_WARNING (expr);
+ location_t loc = EXPR_LOCATION (expr);
+
+ /* This should never be called for C++. */
+ if (c_dialect_cxx ())
+ gcc_unreachable ();
+
+ /* The result of folding may have a NOP_EXPR to set TREE_NO_WARNING. */
+ STRIP_TYPE_NOPS (expr);
+ expr = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (expr), NULL, expr);
+ C_MAYBE_CONST_EXPR_NON_CONST (expr) = non_const;
+ if (nowarning)
+ TREE_NO_WARNING (expr) = 1;
+ protected_set_expr_location (expr, loc);
+
+ return expr;
+}
+
/* Wrap a SAVE_EXPR around EXPR, if appropriate. Like save_expr, but
for C folds the inside expression and wraps a C_MAYBE_CONST_EXPR
around the SAVE_EXPR if needed so that c_fully_fold does not need
expr = c_fully_fold (expr, false, &maybe_const);
expr = save_expr (expr);
if (!maybe_const)
- {
- expr = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (expr), NULL, expr);
- C_MAYBE_CONST_EXPR_NON_CONST (expr) = 1;
- }
+ expr = c_wrap_maybe_const (expr, true);
return expr;
}
"conditional expression"));
}
if (!op1_maybe_const || TREE_CODE (op1) != INTEGER_CST)
- {
- op1 = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (op1),
- NULL, op1);
- C_MAYBE_CONST_EXPR_NON_CONST (op1) = !op1_maybe_const;
- }
+ op1 = c_wrap_maybe_const (op1, !op1_maybe_const);
if (!op2_maybe_const || TREE_CODE (op2) != INTEGER_CST)
- {
- op2 = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (op2),
- NULL, op2);
- C_MAYBE_CONST_EXPR_NON_CONST (op2) = !op2_maybe_const;
- }
+ op2 = c_wrap_maybe_const (op2, !op2_maybe_const);
}
}
}
{
/* Even if this looks constant, do not allow it in a constant
expression. */
- last = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (last), NULL_TREE, last);
- C_MAYBE_CONST_EXPR_NON_CONST (last) = 1;
+ last = c_wrap_maybe_const (last, true);
/* Do not warn if the return value of a statement expression is
unused. */
TREE_NO_WARNING (last) = 1;
if (!in_late_binary_op)
{
if (!op0_maybe_const || TREE_CODE (op0) != INTEGER_CST)
- {
- op0 = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (op0),
- NULL, op0);
- C_MAYBE_CONST_EXPR_NON_CONST (op0) = !op0_maybe_const;
- }
+ op0 = c_wrap_maybe_const (op0, !op0_maybe_const);
if (!op1_maybe_const || TREE_CODE (op1) != INTEGER_CST)
- {
- op1 = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (op1),
- NULL, op1);
- C_MAYBE_CONST_EXPR_NON_CONST (op1) = !op1_maybe_const;
- }
+ op1 = c_wrap_maybe_const (op1, !op1_maybe_const);
}
}
}