107 * it may happen that some of them overflow, while other do not. |
115 * it may happen that some of them overflow, while other do not. |
108 * We must wait for data type checking to determine the exact data type of each expression |
116 * We must wait for data type checking to determine the exact data type of each expression |
109 * before we can decide whether or not we should print out an overflow error message. |
117 * before we can decide whether or not we should print out an overflow error message. |
110 * |
118 * |
111 * For this reason, this visitor merely annotates the abstract syntax tree, and leaves the |
119 * For this reason, this visitor merely annotates the abstract syntax tree, and leaves the |
112 ` actuall printing of errors for the print_datatype_errors_c class! |
120 * actuall printing of errors for the print_datatype_errors_c class! |
113 */ |
121 */ |
114 |
122 |
115 #include "constant_folding.hh" |
123 #include "constant_folding.hh" |
116 #include <typeinfo> |
|
117 #include <limits> |
124 #include <limits> |
|
125 #include <stdint.h> /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */ |
118 #include <math.h> /* required for pow function */ |
126 #include <math.h> /* required for pow function */ |
119 #include <stdlib.h> /* required for malloc() */ |
127 #include <stdlib.h> /* required for malloc() */ |
120 |
128 |
121 |
129 #if 1 |
|
130 #define INT64_MAX (std::numeric_limits< int64_t >::max()) |
|
131 #define INT64_MIN (std::numeric_limits< int64_t >::min()) |
|
132 #else |
|
133 /* An alternative is to use the std::numeric_limits< uint64_t >::min() / max() methods already defined in #include <limits> */ |
|
134 #define __STDC_LIMIT_MACROS /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */ |
|
135 #include <stdint.h> /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */ |
|
136 #endif |
122 |
137 |
123 |
138 |
124 #define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order) ? (symbol1) : (symbol2)) |
139 #define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order) ? (symbol1) : (symbol2)) |
125 #define LAST_(symbol1, symbol2) (((symbol1)->last_order > (symbol2)->last_order) ? (symbol1) : (symbol2)) |
140 #define LAST_(symbol1, symbol2) (((symbol1)->last_order > (symbol2)->last_order) ? (symbol1) : (symbol2)) |
126 |
141 |
170 #define DO_BIN_OPER(dtype, oper)\ |
185 #define DO_BIN_OPER(dtype, oper)\ |
171 if (VALID_CVALUE(dtype, symbol->r_exp) && VALID_CVALUE(dtype, symbol->l_exp)) { \ |
186 if (VALID_CVALUE(dtype, symbol->r_exp) && VALID_CVALUE(dtype, symbol->l_exp)) { \ |
172 NEW_CVALUE(dtype, symbol); \ |
187 NEW_CVALUE(dtype, symbol); \ |
173 SET_CVALUE(dtype, symbol, GET_CVALUE(dtype, symbol->l_exp) oper GET_CVALUE(dtype, symbol->r_exp)); \ |
188 SET_CVALUE(dtype, symbol, GET_CVALUE(dtype, symbol->l_exp) oper GET_CVALUE(dtype, symbol->r_exp)); \ |
174 } |
189 } |
|
190 |
|
191 |
|
192 |
|
193 |
|
194 |
|
195 |
|
196 |
|
197 |
|
198 |
|
199 |
|
200 |
|
201 /* res = a + b */ |
|
202 static void CHECK_OVERFLOW_uint64_SUM(symbol_c *res, symbol_c *a, symbol_c *b) { |
|
203 if (VALID_CVALUE(uint64, res)) |
|
204 /* If sum is smaller than either operand => overflow! */ |
|
205 if (GET_CVALUE(uint64, res) < GET_CVALUE(uint64, a)) |
|
206 SET_OVFLOW(uint64, res); |
|
207 } |
|
208 |
|
209 /* res = a - b */ |
|
210 static void CHECK_OVERFLOW_uint64_SUB(symbol_c *res, symbol_c *a, symbol_c *b) { |
|
211 if (VALID_CVALUE(uint64, res)) |
|
212 /* If diference is larger than a => overflow! */ |
|
213 if (GET_CVALUE(uint64, res) > GET_CVALUE(uint64, a)) |
|
214 SET_OVFLOW(uint64, res); |
|
215 } |
|
216 |
|
217 /* res = a * b */ |
|
218 static void CHECK_OVERFLOW_uint64_MUL(symbol_c *res, symbol_c *a, symbol_c *b) { |
|
219 if (VALID_CVALUE(uint64, res)) |
|
220 if (false /* TODO */) |
|
221 SET_OVFLOW(uint64, res); |
|
222 } |
|
223 |
|
224 /* res = a / b */ |
|
225 static void CHECK_OVERFLOW_uint64_DIV(symbol_c *res, symbol_c *a, symbol_c *b) { |
|
226 if (VALID_CVALUE(uint64, res)) |
|
227 if (false /* TODO */) |
|
228 SET_OVFLOW(uint64, res); |
|
229 } |
|
230 |
|
231 /* res = a MOD b */ |
|
232 static void CHECK_OVERFLOW_uint64_MOD(symbol_c *res, symbol_c *a, symbol_c *b) { |
|
233 if (VALID_CVALUE(uint64, res)) |
|
234 if (false /* TODO */) |
|
235 SET_OVFLOW(uint64, res); |
|
236 } |
|
237 |
|
238 /* res = a + b */ |
|
239 static void CHECK_OVERFLOW_int64_SUM(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
|
240 int64_t a = GET_CVALUE(int64, a_ptr); |
|
241 int64_t b = GET_CVALUE(int64, b_ptr); |
|
242 if (VALID_CVALUE(int64, res)) |
|
243 /* The following test is valid no matter what representation is being used (e.g. two's complement, etc...) */ |
|
244 if (((b > 0) && (a > (INT64_MAX - b))) |
|
245 || ((b < 0) && (a < (INT64_MIN - b)))) |
|
246 SET_OVFLOW(int64, res); |
|
247 } |
|
248 |
|
249 /* res = a - b */ |
|
250 static void CHECK_OVERFLOW_int64_SUB(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
|
251 int64_t a = GET_CVALUE(int64, a_ptr); |
|
252 int64_t b = GET_CVALUE(int64, b_ptr); |
|
253 if (VALID_CVALUE(int64, res)) |
|
254 /* The following test is valid no matter what representation is being used (e.g. two's complement, etc...) */ |
|
255 if (((b > 0) && (a < (INT64_MIN + b))) |
|
256 || ((b < 0) && (a > (INT64_MAX + b)))) |
|
257 SET_OVFLOW(int64, res); |
|
258 } |
|
259 |
|
260 |
|
261 /* res = a * b */ |
|
262 static void CHECK_OVERFLOW_int64_MUL(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
|
263 int64_t a = GET_CVALUE(int64, a_ptr); |
|
264 int64_t b = GET_CVALUE(int64, b_ptr); |
|
265 if (VALID_CVALUE(int64, res)) |
|
266 if ( ( (a > 0) && (b > 0) && (a > (INT64_MAX / b))) |
|
267 || ( (a > 0) && !(b > 0) && (b < (INT64_MIN / a))) |
|
268 || (!(a > 0) && (b > 0) && (a < (INT64_MIN / b))) |
|
269 || (!(a > 0) && !(b > 0) && (a != 0) && (b < (INT64_MAX / a)))) |
|
270 SET_OVFLOW(int64, res); |
|
271 } |
|
272 |
|
273 |
|
274 /* res = a / b */ |
|
275 static void CHECK_OVERFLOW_int64_DIV(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
|
276 int64_t a = GET_CVALUE(int64, a_ptr); |
|
277 int64_t b = GET_CVALUE(int64, b_ptr); |
|
278 if (VALID_CVALUE(int64, res)) |
|
279 if ((b == 0) || ((a == INT64_MIN) && (b == -1))) |
|
280 SET_OVFLOW(int64, res); |
|
281 } |
|
282 |
|
283 |
|
284 /* res = a MOD b */ |
|
285 static void CHECK_OVERFLOW_int64_MOD(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
|
286 int64_t a = GET_CVALUE(int64, a_ptr); |
|
287 int64_t b = GET_CVALUE(int64, b_ptr); |
|
288 /* IEC 61131-3 standard says IN1 MOD IN2 must be equivalent to |
|
289 * IF (IN2 = 0) THEN OUT:=0 ; ELSE OUT:=IN1 - (IN1/IN2)*IN2 ; END_IF |
|
290 * |
|
291 * Note that, when IN1 = INT64_MIN, and IN2 = -1, an overflow occurs in the division, |
|
292 * so although the MOD operation should be OK, acording to the above definition, we actually have an overflow!! |
|
293 * |
|
294 * On the other hand, division by 0 is OK!! |
|
295 */ |
|
296 if (VALID_CVALUE(int64, res)) |
|
297 if ((a == INT64_MIN) && (b == -1)) |
|
298 SET_OVFLOW(int64, res); |
|
299 } |
|
300 |
|
301 |
|
302 /* res = - a */ |
|
303 static void CHECK_OVERFLOW_int64_NEG(symbol_c *res, symbol_c *a_ptr) { |
|
304 int64_t a = GET_CVALUE(int64, a_ptr); |
|
305 if (VALID_CVALUE(int64, res)) |
|
306 if (a == INT64_MIN) |
|
307 SET_OVFLOW(int64, res); |
|
308 } |
|
309 |
|
310 |
|
311 |
|
312 static void CHECK_OVERFLOW_real64(symbol_c *res) { |
|
313 if (VALID_CVALUE(real64, res)) |
|
314 /* NaN => underflow, overflow, number is a higher precision format, is a complex number (IEEE standard) */ |
|
315 if (isnan(GET_CVALUE(real64, res))) |
|
316 SET_OVFLOW(real64, res); |
|
317 } |
|
318 |
|
319 |
|
320 |
|
321 |
|
322 |
|
323 |
|
324 |
|
325 |
|
326 |
175 |
327 |
176 |
328 |
177 |
329 |
178 |
330 |
179 |
331 |
226 symbol->exp->accept(*this); |
378 symbol->exp->accept(*this); |
227 if (!VALID_CVALUE(real64, symbol->exp)) |
379 if (!VALID_CVALUE(real64, symbol->exp)) |
228 return NULL; |
380 return NULL; |
229 NEW_CVALUE(real64, symbol); |
381 NEW_CVALUE(real64, symbol); |
230 SET_CVALUE(real64, symbol, - GET_CVALUE( real64, symbol->exp)); |
382 SET_CVALUE(real64, symbol, - GET_CVALUE( real64, symbol->exp)); |
|
383 CHECK_OVERFLOW_real64(symbol); |
231 return NULL; |
384 return NULL; |
232 } |
385 } |
233 |
386 |
234 /* | '-' integer {$$ = new neg_integer_c($2, locloc(@$));} */ |
387 /* | '-' integer {$$ = new neg_integer_c($2, locloc(@$));} */ |
235 void *constant_folding_c::visit(neg_integer_c *symbol) { |
388 void *constant_folding_c::visit(neg_integer_c *symbol) { |
236 symbol->exp->accept(*this); |
389 symbol->exp->accept(*this); |
237 if (VALID_CVALUE(int64, symbol->exp)) { |
390 if (VALID_CVALUE(int64, symbol->exp)) { |
238 NEW_CVALUE( int64, symbol); |
391 NEW_CVALUE( int64, symbol); |
239 SET_CVALUE( int64, symbol, - GET_CVALUE( int64, symbol->exp)); |
392 SET_CVALUE( int64, symbol, - GET_CVALUE( int64, symbol->exp)); |
240 } |
393 } |
241 /* TODO: check for overflows */ |
394 CHECK_OVERFLOW_int64_NEG(symbol, symbol->exp); |
242 return NULL; |
395 return NULL; |
243 } |
396 } |
244 |
397 |
245 |
398 |
246 void *constant_folding_c::visit(binary_integer_c *symbol) { |
399 void *constant_folding_c::visit(binary_integer_c *symbol) { |
420 DO_BIN_OPER(real64, >=); |
573 DO_BIN_OPER(real64, >=); |
421 return NULL; |
574 return NULL; |
422 } |
575 } |
423 |
576 |
424 |
577 |
425 #define CHECK_OVERFLOW_SUM(dtype)\ |
|
426 if (VALID_CVALUE(dtype, symbol)) \ |
|
427 if ((((std::numeric_limits< dtype##_t >::max() - GET_CVALUE(dtype, symbol->l_exp)) < (GET_CVALUE(dtype, symbol->r_exp))) ? 1 : 0) || \ |
|
428 (((std::numeric_limits< dtype##_t >::min() + GET_CVALUE(dtype, symbol->l_exp)) > (GET_CVALUE(dtype, symbol->r_exp))) ? 1 : 0)) \ |
|
429 SET_OVFLOW(dtype, symbol); |
|
430 #define CHECK_OVERFLOW_real64 \ |
|
431 if (VALID_CVALUE(real64, symbol)) \ |
|
432 /* NaN => underflow, overflow, number is a higher precision format, is a complex number (IEEE standard) */ \ |
|
433 if (isnan(GET_CVALUE(real64, symbol))) \ |
|
434 SET_OVFLOW(real64, symbol); |
|
435 void *constant_folding_c::visit(add_expression_c *symbol) { |
578 void *constant_folding_c::visit(add_expression_c *symbol) { |
436 symbol->l_exp->accept(*this); |
579 symbol->l_exp->accept(*this); |
437 symbol->r_exp->accept(*this); |
580 symbol->r_exp->accept(*this); |
438 DO_BIN_OPER(uint64, +); CHECK_OVERFLOW_SUM(uint64); |
581 DO_BIN_OPER(uint64, +); CHECK_OVERFLOW_uint64_SUM(symbol, symbol->l_exp, symbol->r_exp); |
439 DO_BIN_OPER( int64, +); CHECK_OVERFLOW_SUM( int64); |
582 DO_BIN_OPER( int64, +); CHECK_OVERFLOW_int64_SUM (symbol, symbol->l_exp, symbol->r_exp); |
440 DO_BIN_OPER(real64, +); CHECK_OVERFLOW_real64; |
583 DO_BIN_OPER(real64, +); CHECK_OVERFLOW_real64 (symbol); |
441 return NULL; |
584 return NULL; |
442 } |
585 } |
443 |
586 |
444 |
587 |
445 #define CHECK_OVERFLOW_SUB(dtype)\ |
|
446 if (VALID_CVALUE(dtype, symbol)) \ |
|
447 if ((((std::numeric_limits< dtype##_t >::max() - GET_CVALUE(dtype, symbol->l_exp)) < (-GET_CVALUE(dtype, symbol->r_exp))) ? 1 : 0) || \ |
|
448 (((std::numeric_limits< dtype##_t >::min() + GET_CVALUE(dtype, symbol->l_exp)) > (-GET_CVALUE(dtype, symbol->r_exp))) ? 1 : 0)) \ |
|
449 SET_OVFLOW(dtype, symbol); |
|
450 void *constant_folding_c::visit(sub_expression_c *symbol) { |
588 void *constant_folding_c::visit(sub_expression_c *symbol) { |
451 symbol->l_exp->accept(*this); |
589 symbol->l_exp->accept(*this); |
452 symbol->r_exp->accept(*this); |
590 symbol->r_exp->accept(*this); |
453 DO_BIN_OPER(uint64, -); CHECK_OVERFLOW_SUB(uint64); |
591 DO_BIN_OPER(uint64, -); CHECK_OVERFLOW_uint64_SUB(symbol, symbol->l_exp, symbol->r_exp); |
454 DO_BIN_OPER( int64, -); CHECK_OVERFLOW_SUB( int64); |
592 DO_BIN_OPER( int64, -); CHECK_OVERFLOW_int64_SUB (symbol, symbol->l_exp, symbol->r_exp); |
455 DO_BIN_OPER(real64, -); CHECK_OVERFLOW_real64; |
593 DO_BIN_OPER(real64, -); CHECK_OVERFLOW_real64 (symbol); |
456 return NULL; |
594 return NULL; |
457 } |
595 } |
458 |
596 |
459 |
597 |
460 /* TODO!!! */ |
|
461 #define CHECK_OVERFLOW_MUL(dtype)\ |
|
462 if (VALID_CVALUE(dtype, symbol)) \ |
|
463 if (false) \ |
|
464 SET_OVFLOW(dtype, symbol); |
|
465 void *constant_folding_c::visit(mul_expression_c *symbol) { |
598 void *constant_folding_c::visit(mul_expression_c *symbol) { |
466 symbol->l_exp->accept(*this); |
599 symbol->l_exp->accept(*this); |
467 symbol->r_exp->accept(*this); |
600 symbol->r_exp->accept(*this); |
468 DO_BIN_OPER(uint64, *); CHECK_OVERFLOW_MUL(uint64); |
601 DO_BIN_OPER(uint64, *); CHECK_OVERFLOW_uint64_MUL(symbol, symbol->l_exp, symbol->r_exp); |
469 DO_BIN_OPER( int64, *); CHECK_OVERFLOW_MUL( int64); |
602 DO_BIN_OPER( int64, *); CHECK_OVERFLOW_int64_MUL (symbol, symbol->l_exp, symbol->r_exp); |
470 DO_BIN_OPER(real64, *); CHECK_OVERFLOW_real64; |
603 DO_BIN_OPER(real64, *); CHECK_OVERFLOW_real64 (symbol); |
471 return NULL; |
604 return NULL; |
472 } |
605 } |
473 |
606 |
474 |
607 |
475 |
608 |
476 /* TODO!!! */ |
|
477 #define CHECK_OVERFLOW_DIV(dtype)\ |
|
478 if (VALID_CVALUE(dtype, symbol)) \ |
|
479 if (false) \ |
|
480 SET_OVFLOW(dtype, symbol); |
|
481 void *constant_folding_c::visit(div_expression_c *symbol) { |
609 void *constant_folding_c::visit(div_expression_c *symbol) { |
482 symbol->l_exp->accept(*this); |
610 symbol->l_exp->accept(*this); |
483 symbol->r_exp->accept(*this); |
611 symbol->r_exp->accept(*this); |
484 if (ISZERO_CVALUE(uint64, symbol->r_exp)) {NEW_CVALUE(uint64, symbol); SET_OVFLOW(uint64, symbol);} else {DO_BIN_OPER(uint64, /); CHECK_OVERFLOW_DIV(uint64)}; |
612 if (ISZERO_CVALUE(uint64, symbol->r_exp)) {NEW_CVALUE(uint64, symbol); SET_OVFLOW(uint64, symbol);} else {DO_BIN_OPER(uint64, /); CHECK_OVERFLOW_uint64_DIV(symbol, symbol->l_exp, symbol->r_exp);}; |
485 if (ISZERO_CVALUE( int64, symbol->r_exp)) {NEW_CVALUE( int64, symbol); SET_OVFLOW( int64, symbol);} else {DO_BIN_OPER( int64, /); CHECK_OVERFLOW_DIV( int64)}; |
613 if (ISZERO_CVALUE( int64, symbol->r_exp)) {NEW_CVALUE( int64, symbol); SET_OVFLOW( int64, symbol);} else {DO_BIN_OPER( int64, /); CHECK_OVERFLOW_int64_DIV(symbol, symbol->l_exp, symbol->r_exp);}; |
486 if (ISZERO_CVALUE(real64, symbol->r_exp)) {NEW_CVALUE(real64, symbol); SET_OVFLOW(real64, symbol);} else {DO_BIN_OPER(real64, /); CHECK_OVERFLOW_real64;}; |
614 if (ISZERO_CVALUE(real64, symbol->r_exp)) {NEW_CVALUE(real64, symbol); SET_OVFLOW(real64, symbol);} else {DO_BIN_OPER(real64, /); CHECK_OVERFLOW_real64(symbol);}; |
487 return NULL; |
615 return NULL; |
488 } |
616 } |
489 |
617 |
490 |
618 |
491 /* TODO!!! */ |
|
492 #define CHECK_OVERFLOW_MOD(dtype)\ |
|
493 if (VALID_CVALUE(dtype, symbol)) \ |
|
494 if (false) \ |
|
495 SET_OVFLOW(dtype, symbol); |
|
496 void *constant_folding_c::visit(mod_expression_c *symbol) { |
619 void *constant_folding_c::visit(mod_expression_c *symbol) { |
497 symbol->l_exp->accept(*this); |
620 symbol->l_exp->accept(*this); |
498 symbol->r_exp->accept(*this); |
621 symbol->r_exp->accept(*this); |
499 if (ISZERO_CVALUE(uint64, symbol->r_exp)) {NEW_CVALUE(uint64, symbol); SET_OVFLOW(uint64, symbol);} else {DO_BIN_OPER(uint64, %); CHECK_OVERFLOW_MOD(uint64)}; |
622 /* IEC 61131-3 standard says IN1 MOD IN2 must be equivalent to |
500 if (ISZERO_CVALUE( int64, symbol->r_exp)) {NEW_CVALUE( int64, symbol); SET_OVFLOW( int64, symbol);} else {DO_BIN_OPER( int64, %); CHECK_OVERFLOW_MOD( int64)}; |
623 * IF (IN2 = 0) THEN OUT:=0 ; ELSE OUT:=IN1 - (IN1/IN2)*IN2 ; END_IF |
|
624 * |
|
625 * Note that, when IN1 = INT64_MIN, and IN2 = -1, an overflow occurs in the division, |
|
626 * so although the MOD operation should be OK, acording to the above definition, we actually have an overflow!! |
|
627 */ |
|
628 if (ISZERO_CVALUE(uint64, symbol->r_exp)) {NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, 0);} else {DO_BIN_OPER(uint64, %); CHECK_OVERFLOW_uint64_MOD(symbol, symbol->l_exp, symbol->r_exp);}; |
|
629 if (ISZERO_CVALUE( int64, symbol->r_exp)) {NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, 0);} else {DO_BIN_OPER( int64, %); CHECK_OVERFLOW_int64_MOD(symbol, symbol->l_exp, symbol->r_exp);}; |
501 return NULL; |
630 return NULL; |
502 } |
631 } |
503 |
632 |
504 |
633 |
505 void *constant_folding_c::visit(power_expression_c *symbol) { |
634 void *constant_folding_c::visit(power_expression_c *symbol) { |
515 } |
644 } |
516 if (VALID_CVALUE(real64, symbol->l_exp) && VALID_CVALUE(uint64, symbol->r_exp)) { |
645 if (VALID_CVALUE(real64, symbol->l_exp) && VALID_CVALUE(uint64, symbol->r_exp)) { |
517 NEW_CVALUE(real64, symbol); |
646 NEW_CVALUE(real64, symbol); |
518 SET_CVALUE(real64, symbol, pow(GET_CVALUE(real64, symbol->l_exp), GET_CVALUE(uint64, symbol->r_exp))); |
647 SET_CVALUE(real64, symbol, pow(GET_CVALUE(real64, symbol->l_exp), GET_CVALUE(uint64, symbol->r_exp))); |
519 } |
648 } |
520 CHECK_OVERFLOW_real64; |
649 CHECK_OVERFLOW_real64(symbol); |
521 return NULL; |
650 return NULL; |
522 } |
651 } |
523 |
652 |
524 |
653 |
525 /* TODO!!! */ |
|
526 #define CHECK_OVERFLOW_NEG(dtype)\ |
|
527 if (VALID_CVALUE(dtype, symbol)) \ |
|
528 if (false) \ |
|
529 SET_OVFLOW(dtype, symbol); |
|
530 void *constant_folding_c::visit(neg_expression_c *symbol) { |
654 void *constant_folding_c::visit(neg_expression_c *symbol) { |
531 symbol->exp->accept(*this); |
655 symbol->exp->accept(*this); |
532 if (VALID_CVALUE( int64, symbol->exp)) { |
656 if (VALID_CVALUE( int64, symbol->exp)) { |
533 NEW_CVALUE( int64, symbol); |
657 NEW_CVALUE( int64, symbol); |
534 SET_CVALUE( int64, symbol, - GET_CVALUE( int64, symbol->exp)); |
658 SET_CVALUE( int64, symbol, - GET_CVALUE( int64, symbol->exp)); |
535 } |
659 } |
536 if (VALID_CVALUE(real64, symbol->exp)) { |
660 if (VALID_CVALUE(real64, symbol->exp)) { |
537 NEW_CVALUE(real64, symbol); |
661 NEW_CVALUE(real64, symbol); |
538 SET_CVALUE(real64, symbol, - GET_CVALUE(real64, symbol->exp)); |
662 SET_CVALUE(real64, symbol, - GET_CVALUE(real64, symbol->exp)); |
539 } |
663 } |
540 CHECK_OVERFLOW_NEG( int64); |
664 CHECK_OVERFLOW_int64_NEG(symbol, symbol->exp); |
541 CHECK_OVERFLOW_real64; |
665 CHECK_OVERFLOW_real64(symbol); |
542 return NULL; |
666 return NULL; |
543 } |
667 } |
544 |
668 |
545 |
669 |
546 |
670 |