diff options
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 35 |
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)); |