# HG changeset patch # User Mario de Sousa # Date 1339426724 -3600 # Node ID 983a3b743085ccc1535054cdc8962928afc63eb5 # Parent 70c0456affca05345ea36ee862afbc18ea96d23c Fix 'overflow' detection for real64. diff -r 70c0456affca -r 983a3b743085 stage3/constant_folding.cc --- a/stage3/constant_folding.cc Sun Jun 10 21:51:16 2012 +0100 +++ b/stage3/constant_folding.cc Mon Jun 11 15:58:44 2012 +0100 @@ -118,17 +118,40 @@ #include "constant_folding.hh" #include -#include /* required for pow function */ +#include /* required for pow function, and HUGE_VAL, HUGE_VALF, HUGE_VALL */ #include /* required for malloc() */ -#if 1 -#define UINT64_MAX (std::numeric_limits< uint64_t >::max()) -#define INT64_MAX (std::numeric_limits< int64_t >::max()) -#define INT64_MIN (std::numeric_limits< int64_t >::min()) -#else #define __STDC_LIMIT_MACROS /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */ #include /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */ + + + +#ifndef UINT64_MAX + #define UINT64_MAX (std::numeric_limits< uint64_t >::max()) #endif +#ifndef INT64_MAX + #define INT64_MAX (std::numeric_limits< int64_t >::max()) +#endif +#ifndef INT64_MIN + #define INT64_MIN (std::numeric_limits< int64_t >::min()) +#endif + +#if (real64_t == float) + #define HUGE_VAL64 HUGE_VALF +#elif (real64_t == double) + #define HUGE_VAL64 HUGE_VAL +#elif (real64_t == long_double) + #define HUGE_VAL64 HUGE_VALL +#else + #error Could not determine which data type is being used for real64_t (defined in absyntax.hh). Aborting! +#endif + + + + + + + #define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order) ? (symbol1) : (symbol2)) @@ -342,12 +365,18 @@ -static void CHECK_OVERFLOW_real64(symbol_c *res) { - if (!VALID_CVALUE(real64, res)) - return; - /* NaN => underflow, overflow, number is a higher precision format, is a complex number (IEEE standard) */ - if (isnan(GET_CVALUE(real64, res))) - SET_OVFLOW(real64, res); +static void CHECK_OVERFLOW_real64(symbol_c *res_ptr) { + if (!VALID_CVALUE(real64, res_ptr)) + return; + real64_t res = GET_CVALUE(real64, res_ptr); + /* NaN => underflow, overflow, number is a higher precision format, is a complex number (IEEE standard) */ + /* The IEC 61131-3 clearly states in section '2.5.1.5.2 Numerical functions': + * "It is an error if the result of evaluation of one of these [numerical] functions exceeds the range of values + * specified for the data type of the function output, or if division by zero is attempted." + * For this reason, any operation that has as a result a positive or negative inifinity, is also an error! + */ + if ((isnan(res)) || (res == HUGE_VAL64) || (res == -HUGE_VAL64)) + SET_OVFLOW(real64, res_ptr); } @@ -371,9 +400,10 @@ /* check whether the platform on which the compiler is being run implements IEC 559 floating point data types. */ symbol_c null_symbol; if (! (std::numeric_limits::is_iec559) ) - STAGE3_WARNING(&null_symbol, &null_symbol, "The platform running the compiler does not implement IEC 559 floating point numbers. " + STAGE3_WARNING(&null_symbol, &null_symbol, "The platform running the compiler does not implement IEC 60559 floating point numbers. " "Any error and/or warning messages related to overflow/underflow of the result of operations on REAL/LREAL literals " - " (i.e. constant folding) may themselves be erroneous, although are most probably correct."); + "(i.e. constant folding) may themselves be erroneous, although are most probably correct." + "However, more likely is the possible existance of overflow/underflow errors that are not detected."); }