aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r--gcc/c-common.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 9abd006..b1ac9bc 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -1131,6 +1131,7 @@ 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;
@@ -1142,8 +1143,15 @@ c_fully_fold (tree expr, bool in_init, bool *maybe_const)
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);
+ if (eptype)
+ ret = fold_convert (eptype, ret);
*maybe_const &= maybe_const_itself;
return ret;
}
@@ -1444,6 +1452,15 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
*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. */
@@ -2174,6 +2191,21 @@ tree
convert_and_check (tree type, tree expr)
{
tree result;
+ tree expr_for_warning;
+
+ /* Convert from a value with possible excess precision rather than
+ via the semantic type, but do not warn about values not fitting
+ exactly in the semantic type. */
+ if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR)
+ {
+ tree orig_type = TREE_TYPE (expr);
+ expr = TREE_OPERAND (expr, 0);
+ expr_for_warning = convert (orig_type, expr);
+ if (orig_type == type)
+ return expr_for_warning;
+ }
+ else
+ expr_for_warning = expr;
if (TREE_TYPE (expr) == type)
return expr;
@@ -2181,7 +2213,7 @@ convert_and_check (tree type, tree expr)
result = convert (type, expr);
if (!skip_evaluation && !TREE_OVERFLOW_P (expr) && result != error_mark_node)
- warnings_for_convert_and_check (type, expr, result);
+ warnings_for_convert_and_check (type, expr_for_warning, result);
return result;
}
@@ -3862,6 +3894,7 @@ c_common_truthvalue_conversion (location_t location, tree expr)
case NEGATE_EXPR:
case ABS_EXPR:
case FLOAT_EXPR:
+ case EXCESS_PRECISION_EXPR:
/* These don't change whether an object is nonzero or zero. */
return c_common_truthvalue_conversion (location, TREE_OPERAND (expr, 0));