aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2015-12-02 14:04:38 -0500
committerJason Merrill <jason@gcc.gnu.org>2015-12-02 14:04:38 -0500
commit4250754eea1c10c88f49c9f11b9f912f992b7c42 (patch)
tree08c85cdc811c8da6f75b43930fc94de70352d1ab /gcc/c-family
parente9ea372d08324b38acbc7234e803f8f128c439b8 (diff)
downloadgcc-4250754eea1c10c88f49c9f11b9f912f992b7c42.zip
gcc-4250754eea1c10c88f49c9f11b9f912f992b7c42.tar.gz
gcc-4250754eea1c10c88f49c9f11b9f912f992b7c42.tar.bz2
Define c_fully_fold separately for C and C++.
gcc/c-family/ * c-common.c (c_disable_warnings, c_enable_warnings, c_fully_fold) (c_fully_fold_internal, decl_constant_value_for_optimization): Move to c/c-fold.c. * c-common.h: Don't declare decl_constant_value_for_optimization. gcc/c/ * c-fold.c (c_disable_warnings, c_enable_warnings, c_fully_fold) (c_fully_fold_internal, decl_constant_value_for_optimization): Move from c-common.c. * c-tree.h: Declare decl_constant_value_for_optimization. * Make-lang.in (C_AND_OBJC_OBJS): Add c-fold.o. gcc/cp/ * cp-gimplify.c (c_fully_fold): Define. From-SVN: r231196
Diffstat (limited to 'gcc/c-family')
-rw-r--r--gcc/c-family/ChangeLog7
-rw-r--r--gcc/c-family/c-common.c577
-rw-r--r--gcc/c-family/c-common.h1
3 files changed, 7 insertions, 578 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index b89812f..e32635f 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,10 @@
+2015-12-02 Jason Merrill <jason@redhat.com>
+
+ * c-common.c (c_disable_warnings, c_enable_warnings, c_fully_fold)
+ (c_fully_fold_internal, decl_constant_value_for_optimization):
+ Move to c/c-fold.c.
+ * c-common.h: Don't declare decl_constant_value_for_optimization.
+
2015-12-02 Joseph Myers <joseph@codesourcery.com>
PR c/68162
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 7a9e3b9..40f86e3 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -299,7 +299,6 @@ const struct fname_var_t fname_vars[] =
/* Global visibility options. */
struct visibility_flags visibility_options;
-static tree c_fully_fold_internal (tree expr, bool, bool *, bool *, bool);
static tree check_case_value (location_t, tree);
static bool check_case_bounds (location_t, tree, tree, tree *, tree *,
bool *);
@@ -1095,582 +1094,6 @@ fix_string_type (tree value)
return value;
}
-/* If DISABLE is true, stop issuing warnings. This is used when
- parsing code that we know will not be executed. This function may
- be called multiple times, and works as a stack. */
-
-static void
-c_disable_warnings (bool disable)
-{
- if (disable)
- {
- ++c_inhibit_evaluation_warnings;
- fold_defer_overflow_warnings ();
- }
-}
-
-/* If ENABLE is true, reenable issuing warnings. */
-
-static void
-c_enable_warnings (bool enable)
-{
- if (enable)
- {
- --c_inhibit_evaluation_warnings;
- fold_undefer_and_ignore_overflow_warnings ();
- }
-}
-
-/* Fully fold EXPR, an expression that was not folded (beyond integer
- constant expressions and null pointer constants) when being built
- up. If IN_INIT, this is in a static initializer and certain
- changes are made to the folding done. Clear *MAYBE_CONST if
- MAYBE_CONST is not NULL and EXPR is definitely not a constant
- expression because it contains an evaluated operator (in C99) or an
- operator outside of sizeof returning an integer constant (in C90)
- not permitted in constant expressions, or because it contains an
- evaluated arithmetic overflow. (*MAYBE_CONST should typically be
- set to true by callers before calling this function.) Return the
- folded expression. Function arguments have already been folded
- before calling this function, as have the contents of SAVE_EXPR,
- TARGET_EXPR, BIND_EXPR, VA_ARG_EXPR, OBJ_TYPE_REF and
- C_MAYBE_CONST_EXPR. */
-
-tree
-c_fully_fold (tree expr, bool in_init, bool *maybe_const)
-{
- tree ret;
- tree eptype = NULL_TREE;
- bool dummy = true;
- bool maybe_const_itself = true;
- location_t loc = EXPR_LOCATION (expr);
-
- /* This function is not relevant to C++ because C++ folds while
- parsing, and may need changes to be correct for C++ when C++
- stops folding while parsing. */
- if (c_dialect_cxx ())
- gcc_unreachable ();
-
- if (!maybe_const)
- maybe_const = &dummy;
- if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR)
- {
- eptype = TREE_TYPE (expr);
- expr = TREE_OPERAND (expr, 0);
- }
- ret = c_fully_fold_internal (expr, in_init, maybe_const,
- &maybe_const_itself, false);
- if (eptype)
- ret = fold_convert_loc (loc, eptype, ret);
- *maybe_const &= maybe_const_itself;
- return ret;
-}
-
-/* Internal helper for c_fully_fold. EXPR and IN_INIT are as for
- c_fully_fold. *MAYBE_CONST_OPERANDS is cleared because of operands
- not permitted, while *MAYBE_CONST_ITSELF is cleared because of
- arithmetic overflow (for C90, *MAYBE_CONST_OPERANDS is carried from
- both evaluated and unevaluated subexpressions while
- *MAYBE_CONST_ITSELF is carried from only evaluated
- subexpressions). FOR_INT_CONST indicates if EXPR is an expression
- with integer constant operands, and if any of the operands doesn't
- get folded to an integer constant, don't fold the expression itself. */
-
-static tree
-c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
- bool *maybe_const_itself, bool for_int_const)
-{
- tree ret = expr;
- enum tree_code code = TREE_CODE (expr);
- enum tree_code_class kind = TREE_CODE_CLASS (code);
- location_t loc = EXPR_LOCATION (expr);
- tree op0, op1, op2, op3;
- tree orig_op0, orig_op1, orig_op2;
- bool op0_const = true, op1_const = true, op2_const = true;
- bool op0_const_self = true, op1_const_self = true, op2_const_self = true;
- bool nowarning = TREE_NO_WARNING (expr);
- bool unused_p;
- source_range old_range;
-
- /* This function is not relevant to C++ because C++ folds while
- parsing, and may need changes to be correct for C++ when C++
- stops folding while parsing. */
- if (c_dialect_cxx ())
- gcc_unreachable ();
-
- /* Constants, declarations, statements, errors, SAVE_EXPRs and
- anything else not counted as an expression cannot usefully be
- folded further at this point. */
- if (!IS_EXPR_CODE_CLASS (kind)
- || kind == tcc_statement
- || code == SAVE_EXPR)
- return expr;
-
- if (IS_EXPR_CODE_CLASS (kind))
- old_range = EXPR_LOCATION_RANGE (expr);
-
- /* Operands of variable-length expressions (function calls) have
- already been folded, as have __builtin_* function calls, and such
- expressions cannot occur in constant expressions. */
- if (kind == tcc_vl_exp)
- {
- *maybe_const_operands = false;
- ret = fold (expr);
- goto out;
- }
-
- if (code == C_MAYBE_CONST_EXPR)
- {
- tree pre = C_MAYBE_CONST_EXPR_PRE (expr);
- tree inner = C_MAYBE_CONST_EXPR_EXPR (expr);
- if (C_MAYBE_CONST_EXPR_NON_CONST (expr))
- *maybe_const_operands = false;
- if (C_MAYBE_CONST_EXPR_INT_OPERANDS (expr))
- {
- *maybe_const_itself = false;
- inner = c_fully_fold_internal (inner, in_init, maybe_const_operands,
- maybe_const_itself, true);
- }
- if (pre && !in_init)
- ret = build2 (COMPOUND_EXPR, TREE_TYPE (expr), pre, inner);
- else
- ret = inner;
- goto out;
- }
-
- /* Assignment, increment, decrement, function call and comma
- operators, and statement expressions, cannot occur in constant
- expressions if evaluated / outside of sizeof. (Function calls
- were handled above, though VA_ARG_EXPR is treated like a function
- call here, and statement expressions are handled through
- C_MAYBE_CONST_EXPR to avoid folding inside them.) */
- switch (code)
- {
- case MODIFY_EXPR:
- case PREDECREMENT_EXPR:
- case PREINCREMENT_EXPR:
- case POSTDECREMENT_EXPR:
- case POSTINCREMENT_EXPR:
- case COMPOUND_EXPR:
- *maybe_const_operands = false;
- break;
-
- case VA_ARG_EXPR:
- case TARGET_EXPR:
- case BIND_EXPR:
- case OBJ_TYPE_REF:
- *maybe_const_operands = false;
- ret = fold (expr);
- goto out;
-
- default:
- break;
- }
-
- /* Fold individual tree codes as appropriate. */
- switch (code)
- {
- case COMPOUND_LITERAL_EXPR:
- /* Any non-constancy will have been marked in a containing
- C_MAYBE_CONST_EXPR; there is no more folding to do here. */
- goto out;
-
- case COMPONENT_REF:
- orig_op0 = op0 = TREE_OPERAND (expr, 0);
- op1 = TREE_OPERAND (expr, 1);
- op2 = TREE_OPERAND (expr, 2);
- op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
- maybe_const_itself, for_int_const);
- STRIP_TYPE_NOPS (op0);
- if (op0 != orig_op0)
- ret = build3 (COMPONENT_REF, TREE_TYPE (expr), op0, op1, op2);
- if (ret != expr)
- {
- TREE_READONLY (ret) = TREE_READONLY (expr);
- TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
- }
- goto out;
-
- case ARRAY_REF:
- orig_op0 = op0 = TREE_OPERAND (expr, 0);
- orig_op1 = op1 = TREE_OPERAND (expr, 1);
- op2 = TREE_OPERAND (expr, 2);
- op3 = TREE_OPERAND (expr, 3);
- op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
- maybe_const_itself, for_int_const);
- STRIP_TYPE_NOPS (op0);
- op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
- maybe_const_itself, for_int_const);
- 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);
- if (ret != expr)
- {
- TREE_READONLY (ret) = TREE_READONLY (expr);
- TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr);
- TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
- }
- ret = fold (ret);
- goto out;
-
- case COMPOUND_EXPR:
- case MODIFY_EXPR:
- case PREDECREMENT_EXPR:
- case PREINCREMENT_EXPR:
- case POSTDECREMENT_EXPR:
- case POSTINCREMENT_EXPR:
- case PLUS_EXPR:
- case MINUS_EXPR:
- case MULT_EXPR:
- case POINTER_PLUS_EXPR:
- case TRUNC_DIV_EXPR:
- case CEIL_DIV_EXPR:
- case FLOOR_DIV_EXPR:
- case TRUNC_MOD_EXPR:
- case RDIV_EXPR:
- case EXACT_DIV_EXPR:
- case LSHIFT_EXPR:
- case RSHIFT_EXPR:
- case BIT_IOR_EXPR:
- case BIT_XOR_EXPR:
- case BIT_AND_EXPR:
- case LT_EXPR:
- case LE_EXPR:
- case GT_EXPR:
- case GE_EXPR:
- case EQ_EXPR:
- case NE_EXPR:
- case COMPLEX_EXPR:
- case TRUTH_AND_EXPR:
- case TRUTH_OR_EXPR:
- case TRUTH_XOR_EXPR:
- case UNORDERED_EXPR:
- case ORDERED_EXPR:
- case UNLT_EXPR:
- case UNLE_EXPR:
- case UNGT_EXPR:
- case UNGE_EXPR:
- case UNEQ_EXPR:
- /* Binary operations evaluating both arguments (increment and
- decrement are binary internally in GCC). */
- orig_op0 = op0 = TREE_OPERAND (expr, 0);
- orig_op1 = op1 = TREE_OPERAND (expr, 1);
- op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
- maybe_const_itself, for_int_const);
- STRIP_TYPE_NOPS (op0);
- if (code != MODIFY_EXPR
- && code != PREDECREMENT_EXPR
- && code != PREINCREMENT_EXPR
- && code != POSTDECREMENT_EXPR
- && code != POSTINCREMENT_EXPR)
- op0 = decl_constant_value_for_optimization (op0);
- /* The RHS of a MODIFY_EXPR was fully folded when building that
- expression for the sake of conversion warnings. */
- if (code != MODIFY_EXPR)
- op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
- maybe_const_itself, for_int_const);
- STRIP_TYPE_NOPS (op1);
- op1 = decl_constant_value_for_optimization (op1);
-
- if (for_int_const && (TREE_CODE (op0) != INTEGER_CST
- || TREE_CODE (op1) != INTEGER_CST))
- goto out;
-
- if (op0 != orig_op0 || op1 != orig_op1 || in_init)
- ret = in_init
- ? fold_build2_initializer_loc (loc, code, TREE_TYPE (expr), op0, op1)
- : fold_build2_loc (loc, code, TREE_TYPE (expr), op0, op1);
- else
- ret = fold (expr);
- if (TREE_OVERFLOW_P (ret)
- && !TREE_OVERFLOW_P (op0)
- && !TREE_OVERFLOW_P (op1))
- overflow_warning (EXPR_LOC_OR_LOC (expr, input_location), ret);
- if (code == LSHIFT_EXPR
- && TREE_CODE (orig_op0) != INTEGER_CST
- && TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
- && TREE_CODE (op0) == INTEGER_CST
- && c_inhibit_evaluation_warnings == 0
- && tree_int_cst_sgn (op0) < 0)
- warning_at (loc, OPT_Wshift_negative_value,
- "left shift of negative value");
- if ((code == LSHIFT_EXPR || code == RSHIFT_EXPR)
- && TREE_CODE (orig_op1) != INTEGER_CST
- && TREE_CODE (op1) == INTEGER_CST
- && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
- || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE)
- && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE
- && c_inhibit_evaluation_warnings == 0)
- {
- if (tree_int_cst_sgn (op1) < 0)
- warning_at (loc, OPT_Wshift_count_negative,
- (code == LSHIFT_EXPR
- ? G_("left shift count is negative")
- : G_("right shift count is negative")));
- else if (compare_tree_int (op1,
- TYPE_PRECISION (TREE_TYPE (orig_op0)))
- >= 0)
- warning_at (loc, OPT_Wshift_count_overflow,
- (code == LSHIFT_EXPR
- ? G_("left shift count >= width of type")
- : G_("right shift count >= width of type")));
- }
- if (code == LSHIFT_EXPR
- /* If either OP0 has been folded to INTEGER_CST... */
- && ((TREE_CODE (orig_op0) != INTEGER_CST
- && TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
- && TREE_CODE (op0) == INTEGER_CST)
- /* ...or if OP1 has been folded to INTEGER_CST... */
- || (TREE_CODE (orig_op1) != INTEGER_CST
- && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE
- && TREE_CODE (op1) == INTEGER_CST))
- && c_inhibit_evaluation_warnings == 0)
- /* ...then maybe we can detect an overflow. */
- maybe_warn_shift_overflow (loc, op0, op1);
- if ((code == TRUNC_DIV_EXPR
- || code == CEIL_DIV_EXPR
- || code == FLOOR_DIV_EXPR
- || code == EXACT_DIV_EXPR
- || code == TRUNC_MOD_EXPR)
- && TREE_CODE (orig_op1) != INTEGER_CST
- && TREE_CODE (op1) == INTEGER_CST
- && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
- || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE)
- && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE)
- warn_for_div_by_zero (loc, op1);
- goto out;
-
- case INDIRECT_REF:
- case FIX_TRUNC_EXPR:
- case FLOAT_EXPR:
- CASE_CONVERT:
- case ADDR_SPACE_CONVERT_EXPR:
- case VIEW_CONVERT_EXPR:
- case NON_LVALUE_EXPR:
- case NEGATE_EXPR:
- case BIT_NOT_EXPR:
- case TRUTH_NOT_EXPR:
- case ADDR_EXPR:
- case CONJ_EXPR:
- case REALPART_EXPR:
- case IMAGPART_EXPR:
- /* Unary operations. */
- orig_op0 = op0 = TREE_OPERAND (expr, 0);
- op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
- maybe_const_itself, for_int_const);
- STRIP_TYPE_NOPS (op0);
- if (code != ADDR_EXPR && code != REALPART_EXPR && code != IMAGPART_EXPR)
- op0 = decl_constant_value_for_optimization (op0);
-
- if (for_int_const && TREE_CODE (op0) != INTEGER_CST)
- goto out;
-
- /* ??? Cope with user tricks that amount to offsetof. The middle-end is
- not prepared to deal with them if they occur in initializers. */
- if (op0 != orig_op0
- && code == ADDR_EXPR
- && (op1 = get_base_address (op0)) != NULL_TREE
- && INDIRECT_REF_P (op1)
- && TREE_CONSTANT (TREE_OPERAND (op1, 0)))
- ret = fold_convert_loc (loc, TREE_TYPE (expr), fold_offsetof_1 (op0));
- else if (op0 != orig_op0 || in_init)
- ret = in_init
- ? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0)
- : fold_build1_loc (loc, code, TREE_TYPE (expr), op0);
- else
- ret = fold (expr);
- if (code == INDIRECT_REF
- && ret != expr
- && INDIRECT_REF_P (ret))
- {
- TREE_READONLY (ret) = TREE_READONLY (expr);
- TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr);
- TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
- }
- switch (code)
- {
- case FIX_TRUNC_EXPR:
- case FLOAT_EXPR:
- CASE_CONVERT:
- /* Don't warn about explicit conversions. We will already
- have warned about suspect implicit conversions. */
- break;
-
- default:
- if (TREE_OVERFLOW_P (ret) && !TREE_OVERFLOW_P (op0))
- overflow_warning (EXPR_LOCATION (expr), ret);
- break;
- }
- goto out;
-
- case TRUTH_ANDIF_EXPR:
- case TRUTH_ORIF_EXPR:
- /* Binary operations not necessarily evaluating both
- arguments. */
- 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,
- for_int_const);
- STRIP_TYPE_NOPS (op0);
-
- unused_p = (op0 == (code == TRUTH_ANDIF_EXPR
- ? truthvalue_false_node
- : truthvalue_true_node));
- c_disable_warnings (unused_p);
- op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self,
- for_int_const);
- STRIP_TYPE_NOPS (op1);
- c_enable_warnings (unused_p);
-
- if (for_int_const
- && (TREE_CODE (op0) != INTEGER_CST
- /* Require OP1 be an INTEGER_CST only if it's evaluated. */
- || (!unused_p && TREE_CODE (op1) != INTEGER_CST)))
- goto out;
-
- if (op0 != orig_op0 || op1 != orig_op1 || in_init)
- ret = in_init
- ? fold_build2_initializer_loc (loc, code, TREE_TYPE (expr), op0, op1)
- : fold_build2_loc (loc, code, TREE_TYPE (expr), op0, op1);
- else
- ret = fold (expr);
- *maybe_const_operands &= op0_const;
- *maybe_const_itself &= op0_const_self;
- if (!(flag_isoc99
- && op0_const
- && op0_const_self
- && (code == TRUTH_ANDIF_EXPR
- ? op0 == truthvalue_false_node
- : op0 == truthvalue_true_node)))
- *maybe_const_operands &= op1_const;
- if (!(op0_const
- && op0_const_self
- && (code == TRUTH_ANDIF_EXPR
- ? op0 == truthvalue_false_node
- : op0 == truthvalue_true_node)))
- *maybe_const_itself &= op1_const_self;
- goto out;
-
- case COND_EXPR:
- orig_op0 = op0 = TREE_OPERAND (expr, 0);
- orig_op1 = op1 = TREE_OPERAND (expr, 1);
- orig_op2 = op2 = TREE_OPERAND (expr, 2);
- op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self,
- for_int_const);
-
- STRIP_TYPE_NOPS (op0);
- c_disable_warnings (op0 == truthvalue_false_node);
- op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self,
- for_int_const);
- STRIP_TYPE_NOPS (op1);
- c_enable_warnings (op0 == truthvalue_false_node);
-
- c_disable_warnings (op0 == truthvalue_true_node);
- op2 = c_fully_fold_internal (op2, in_init, &op2_const, &op2_const_self,
- for_int_const);
- STRIP_TYPE_NOPS (op2);
- c_enable_warnings (op0 == truthvalue_true_node);
-
- if (for_int_const
- && (TREE_CODE (op0) != INTEGER_CST
- /* Only the evaluated operand must be an INTEGER_CST. */
- || (op0 == truthvalue_true_node
- ? TREE_CODE (op1) != INTEGER_CST
- : TREE_CODE (op2) != INTEGER_CST)))
- goto out;
-
- if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2)
- ret = fold_build3_loc (loc, code, TREE_TYPE (expr), op0, op1, op2);
- else
- ret = fold (expr);
- *maybe_const_operands &= op0_const;
- *maybe_const_itself &= op0_const_self;
- if (!(flag_isoc99
- && op0_const
- && op0_const_self
- && op0 == truthvalue_false_node))
- *maybe_const_operands &= op1_const;
- if (!(op0_const
- && op0_const_self
- && op0 == truthvalue_false_node))
- *maybe_const_itself &= op1_const_self;
- if (!(flag_isoc99
- && op0_const
- && op0_const_self
- && op0 == truthvalue_true_node))
- *maybe_const_operands &= op2_const;
- if (!(op0_const
- && op0_const_self
- && op0 == truthvalue_true_node))
- *maybe_const_itself &= op2_const_self;
- goto out;
-
- case EXCESS_PRECISION_EXPR:
- /* Each case where an operand with excess precision may be
- encountered must remove the EXCESS_PRECISION_EXPR around
- inner operands and possibly put one around the whole
- expression or possibly convert to the semantic type (which
- c_fully_fold does); we cannot tell at this stage which is
- appropriate in any particular case. */
- gcc_unreachable ();
-
- default:
- /* Various codes may appear through folding built-in functions
- and their arguments. */
- goto out;
- }
-
- out:
- /* Some folding may introduce NON_LVALUE_EXPRs; all lvalue checks
- have been done by this point, so remove them again. */
- nowarning |= TREE_NO_WARNING (ret);
- STRIP_TYPE_NOPS (ret);
- if (nowarning && !TREE_NO_WARNING (ret))
- {
- if (!CAN_HAVE_LOCATION_P (ret))
- ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
- TREE_NO_WARNING (ret) = 1;
- }
- if (ret != expr)
- {
- protected_set_expr_location (ret, loc);
- if (IS_EXPR_CODE_CLASS (kind))
- set_source_range (ret, old_range.m_start, old_range.m_finish);
- }
- return ret;
-}
-
-/* If not optimizing, EXP is not a VAR_DECL, or EXP has array type,
- return EXP. Otherwise, return either EXP or its known constant
- value (if it has one), but return EXP if EXP has mode BLKmode. ???
- Is the BLKmode test appropriate? */
-
-tree
-decl_constant_value_for_optimization (tree exp)
-{
- tree ret;
-
- /* This function is only used by C, for c_fully_fold and other
- optimization, and may not be correct for C++. */
- if (c_dialect_cxx ())
- gcc_unreachable ();
-
- if (!optimize
- || !VAR_P (exp)
- || TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
- || DECL_MODE (exp) == BLKmode)
- return exp;
-
- ret = decl_constant_value (exp);
- /* Avoid unwanted tree sharing between the initializer and current
- function's body where the tree can be modified e.g. by the
- gimplifier. */
- if (ret != exp && TREE_STATIC (exp))
- ret = unshare_expr (ret);
- return ret;
-}
-
/* Print a warning if a constant expression had overflow in folding.
Invoke this function on every expression that the language
requires to be a constant expression.
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 6e60e34..ef64e6b 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -809,7 +809,6 @@ extern enum conversion_safety unsafe_conversion_p (location_t, tree, tree,
bool);
extern bool decl_with_nonnull_addr_p (const_tree);
extern tree c_fully_fold (tree, bool, bool *);
-extern tree decl_constant_value_for_optimization (tree);
extern tree c_wrap_maybe_const (tree, bool);
extern tree c_save_expr (tree);
extern tree c_common_truthvalue_conversion (location_t, tree);