116 * actuall printing of errors for the print_datatype_errors_c class! |
116 * actuall printing of errors for the print_datatype_errors_c class! |
117 */ |
117 */ |
118 |
118 |
119 #include "constant_folding.hh" |
119 #include "constant_folding.hh" |
120 #include <limits> |
120 #include <limits> |
121 #include <math.h> /* required for pow function */ |
121 #include <math.h> /* required for pow function, and HUGE_VAL, HUGE_VALF, HUGE_VALL */ |
122 #include <stdlib.h> /* required for malloc() */ |
122 #include <stdlib.h> /* required for malloc() */ |
123 |
123 |
124 #if 1 |
|
125 #define UINT64_MAX (std::numeric_limits< uint64_t >::max()) |
|
126 #define INT64_MAX (std::numeric_limits< int64_t >::max()) |
|
127 #define INT64_MIN (std::numeric_limits< int64_t >::min()) |
|
128 #else |
|
129 #define __STDC_LIMIT_MACROS /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */ |
124 #define __STDC_LIMIT_MACROS /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */ |
130 #include <stdint.h> /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */ |
125 #include <stdint.h> /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */ |
|
126 |
|
127 |
|
128 |
|
129 #ifndef UINT64_MAX |
|
130 #define UINT64_MAX (std::numeric_limits< uint64_t >::max()) |
131 #endif |
131 #endif |
|
132 #ifndef INT64_MAX |
|
133 #define INT64_MAX (std::numeric_limits< int64_t >::max()) |
|
134 #endif |
|
135 #ifndef INT64_MIN |
|
136 #define INT64_MIN (std::numeric_limits< int64_t >::min()) |
|
137 #endif |
|
138 |
|
139 #if (real64_t == float) |
|
140 #define HUGE_VAL64 HUGE_VALF |
|
141 #elif (real64_t == double) |
|
142 #define HUGE_VAL64 HUGE_VAL |
|
143 #elif (real64_t == long_double) |
|
144 #define HUGE_VAL64 HUGE_VALL |
|
145 #else |
|
146 #error Could not determine which data type is being used for real64_t (defined in absyntax.hh). Aborting! |
|
147 #endif |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 |
|
154 |
132 |
155 |
133 |
156 |
134 #define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order) ? (symbol1) : (symbol2)) |
157 #define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order) ? (symbol1) : (symbol2)) |
135 #define LAST_(symbol1, symbol2) (((symbol1)->last_order > (symbol2)->last_order) ? (symbol1) : (symbol2)) |
158 #define LAST_(symbol1, symbol2) (((symbol1)->last_order > (symbol2)->last_order) ? (symbol1) : (symbol2)) |
136 |
159 |
340 SET_OVFLOW(int64, res); |
363 SET_OVFLOW(int64, res); |
341 } |
364 } |
342 |
365 |
343 |
366 |
344 |
367 |
345 static void CHECK_OVERFLOW_real64(symbol_c *res) { |
368 static void CHECK_OVERFLOW_real64(symbol_c *res_ptr) { |
346 if (!VALID_CVALUE(real64, res)) |
369 if (!VALID_CVALUE(real64, res_ptr)) |
347 return; |
370 return; |
348 /* NaN => underflow, overflow, number is a higher precision format, is a complex number (IEEE standard) */ |
371 real64_t res = GET_CVALUE(real64, res_ptr); |
349 if (isnan(GET_CVALUE(real64, res))) |
372 /* NaN => underflow, overflow, number is a higher precision format, is a complex number (IEEE standard) */ |
350 SET_OVFLOW(real64, res); |
373 /* The IEC 61131-3 clearly states in section '2.5.1.5.2 Numerical functions': |
|
374 * "It is an error if the result of evaluation of one of these [numerical] functions exceeds the range of values |
|
375 * specified for the data type of the function output, or if division by zero is attempted." |
|
376 * For this reason, any operation that has as a result a positive or negative inifinity, is also an error! |
|
377 */ |
|
378 if ((isnan(res)) || (res == HUGE_VAL64) || (res == -HUGE_VAL64)) |
|
379 SET_OVFLOW(real64, res_ptr); |
351 } |
380 } |
352 |
381 |
353 |
382 |
354 |
383 |
355 |
384 |
369 current_display_error_level = 0; |
398 current_display_error_level = 0; |
370 |
399 |
371 /* check whether the platform on which the compiler is being run implements IEC 559 floating point data types. */ |
400 /* check whether the platform on which the compiler is being run implements IEC 559 floating point data types. */ |
372 symbol_c null_symbol; |
401 symbol_c null_symbol; |
373 if (! (std::numeric_limits<real64_t>::is_iec559) ) |
402 if (! (std::numeric_limits<real64_t>::is_iec559) ) |
374 STAGE3_WARNING(&null_symbol, &null_symbol, "The platform running the compiler does not implement IEC 559 floating point numbers. " |
403 STAGE3_WARNING(&null_symbol, &null_symbol, "The platform running the compiler does not implement IEC 60559 floating point numbers. " |
375 "Any error and/or warning messages related to overflow/underflow of the result of operations on REAL/LREAL literals " |
404 "Any error and/or warning messages related to overflow/underflow of the result of operations on REAL/LREAL literals " |
376 " (i.e. constant folding) may themselves be erroneous, although are most probably correct."); |
405 "(i.e. constant folding) may themselves be erroneous, although are most probably correct." |
|
406 "However, more likely is the possible existance of overflow/underflow errors that are not detected."); |
377 } |
407 } |
378 |
408 |
379 |
409 |
380 constant_folding_c::~constant_folding_c(void) { |
410 constant_folding_c::~constant_folding_c(void) { |
381 } |
411 } |