From: Richard Kenner Date: Sun, 13 Mar 1994 13:30:50 +0000 (-0500) Subject: (force_fit_value): Operate on REAL_CST as well. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=649ff3b44f1adaca0ee5c2a51f568f334cb476eb;p=gcc.git (force_fit_value): Operate on REAL_CST as well. (real_value_truncate): Don't use its own handler. (const_binop): Set overflow on FP error and call force_fit_type. (fold_convert): Likewise. From-SVN: r6768 --- diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 304eac88f7e..453af6cd0dd 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -140,7 +140,10 @@ decode (shorts, low, hi) that don't belong in the type. Yield 1 if a signed overflow occurs, 0 otherwise. If OVERFLOW is nonzero, a signed overflow has already occurred - in calculating T, so propagate it. */ + in calculating T, so propagate it. + + Make the real constant T valid for its type by calling CHECK_FLOAT_VALUE, + if it exists. */ int force_fit_type (t, overflow) @@ -150,7 +153,16 @@ force_fit_type (t, overflow) HOST_WIDE_INT low, high; register int prec; - if (TREE_CODE (t) != INTEGER_CST) + if (TREE_CODE (t) == REAL_CST) + { +#ifdef CHECK_FLOAT_VALUE + CHECK_FLOAT_VALUE (TYPE_MODE (TREE_TYPE (t)), TREE_REAL_CST (t), + overflow); +#endif + return overflow; + } + + else if (TREE_CODE (t) != INTEGER_CST) return overflow; low = TREE_INT_CST_LOW (t); @@ -803,34 +815,19 @@ div_and_round_double (code, uns, } #ifndef REAL_ARITHMETIC -/* Effectively truncate a real value to represent - the nearest possible value in a narrower mode. - The result is actually represented in the same data type as the argument, - but its value is usually different. */ +/* Effectively truncate a real value to represent the nearest possible value + in a narrower mode. The result is actually represented in the same data + type as the argument, but its value is usually different. + + A trap may occur during the FP operations and it is the responsibility + of the calling function to have a handler established. */ REAL_VALUE_TYPE real_value_truncate (mode, arg) enum machine_mode mode; REAL_VALUE_TYPE arg; { -#ifdef __STDC__ - /* Make sure the value is actually stored in memory before we turn off - the handler. */ - volatile -#endif - REAL_VALUE_TYPE value; - jmp_buf handler, old_handler; - int handled; - - if (setjmp (handler)) - { - error ("floating overflow"); - return dconst0; - } - handled = push_float_handler (handler, old_handler); - value = REAL_VALUE_TRUNCATE (mode, arg); - pop_float_handler (handled, old_handler); - return value; + return REAL_VALUE_TRUNCATE (mode, arg); } #if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT @@ -1333,18 +1330,19 @@ const_binop (code, arg1, arg2, notrunc) #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC) if (TREE_CODE (arg1) == REAL_CST) { - REAL_VALUE_TYPE d1; - REAL_VALUE_TYPE d2; + REAL_VALUE_TYPE d1 = TREE_REAL_CST (arg1); + REAL_VALUE_TYPE d2 = TREE_REAL_CST (arg2); + int overflow = 0; REAL_VALUE_TYPE value; tree t; - d1 = TREE_REAL_CST (arg1); - d2 = TREE_REAL_CST (arg2); if (setjmp (float_error)) { - pedwarn ("floating overflow in constant expression"); - return build (code, TREE_TYPE (arg1), arg1, arg2); + t = copy_node (arg1); + overflow = 1; + goto got_float; } + set_float_handler (float_error); #ifdef REAL_ARITHMETIC @@ -1387,7 +1385,16 @@ const_binop (code, arg1, arg2, notrunc) #endif /* no REAL_ARITHMETIC */ t = build_real (TREE_TYPE (arg1), real_value_truncate (TYPE_MODE (TREE_TYPE (arg1)), value)); + got_float: set_float_handler (NULL_PTR); + + TREE_OVERFLOW (t) + = (force_fit_type (t, overflow) + | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2)); + TREE_CONSTANT_OVERFLOW (t) + = TREE_OVERFLOW (t) + | TREE_CONSTANT_OVERFLOW (arg1) + | TREE_CONSTANT_OVERFLOW (arg2); return t; } #endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */ @@ -1540,6 +1547,7 @@ fold_convert (t, arg1) register tree arg1; { register tree type = TREE_TYPE (t); + int overflow = 0; if (TREE_CODE (type) == POINTER_TYPE || INTEGRAL_TYPE_P (type)) { @@ -1583,10 +1591,8 @@ fold_convert (t, arg1) u++; #endif if (! (REAL_VALUES_LESS (l, x) && REAL_VALUES_LESS (x, u))) - { - pedwarn ("real constant out of range for integer conversion"); - return t; - } + overflow = 1; + #ifndef REAL_ARITHMETIC { REAL_VALUE_TYPE d; @@ -1619,7 +1625,10 @@ fold_convert (t, arg1) } #endif TREE_TYPE (t) = type; - force_fit_type (t, 0); + TREE_OVERFLOW (t) + = TREE_OVERFLOW (arg1) | force_fit_type (t, overflow); + TREE_CONSTANT_OVERFLOW (t) + = TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1); } #endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */ TREE_TYPE (t) = type; @@ -1634,14 +1643,21 @@ fold_convert (t, arg1) { if (setjmp (float_error)) { - pedwarn ("floating overflow in constant expression"); - return t; + overflow = 1; + t = copy_node (arg1); + goto got_it; } set_float_handler (float_error); t = build_real (type, real_value_truncate (TYPE_MODE (type), TREE_REAL_CST (arg1))); set_float_handler (NULL_PTR); + + got_it: + TREE_OVERFLOW (t) + = TREE_OVERFLOW (arg1) | force_fit_type (t, overflow); + TREE_CONSTANT_OVERFLOW (t) + = TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1); return t; } }