192 |
188 |
193 |
189 |
194 |
190 |
195 |
191 |
196 |
192 |
197 |
193 /* NOTE: |
198 |
194 * Most of the conditions to detect overflows on signed and unsigned integer operations were adapted from |
|
195 * https://www.securecoding.cert.org/confluence/display/seccode/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow?showComments=false |
|
196 * https://www.securecoding.cert.org/confluence/display/seccode/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap |
|
197 */ |
|
198 |
|
199 /* NOTE: If at all possible, all overflow tests are done by pre-condition tests, i.e. tests that |
|
200 * can be run _before_ the operation is executed, and therefore without accessing the result! |
|
201 * |
|
202 * The exception is for real/floating point values, that simply test if the result is NaN (not a number). |
|
203 */ |
199 |
204 |
200 /* res = a + b */ |
205 /* res = a + b */ |
201 static void CHECK_OVERFLOW_uint64_SUM(symbol_c *res, symbol_c *a, symbol_c *b) { |
206 static void CHECK_OVERFLOW_uint64_SUM(symbol_c *res, symbol_c *a, symbol_c *b) { |
202 if (VALID_CVALUE(uint64, res)) |
207 if (!VALID_CVALUE(uint64, res)) |
203 /* If sum is smaller than either operand => overflow! */ |
208 return; |
204 if (GET_CVALUE(uint64, res) < GET_CVALUE(uint64, a)) |
209 /* Test by post-condition: If sum is smaller than either operand => overflow! */ |
205 SET_OVFLOW(uint64, res); |
210 // if (GET_CVALUE(uint64, res) < GET_CVALUE(uint64, a)) |
206 } |
211 /* Test by pre-condition: If (UINT64_MAX - a) < b => overflow! */ |
|
212 if ((UINT64_MAX - GET_CVALUE(uint64, a)) < GET_CVALUE(uint64, b)) |
|
213 SET_OVFLOW(uint64, res); |
|
214 } |
|
215 |
207 |
216 |
208 /* res = a - b */ |
217 /* res = a - b */ |
209 static void CHECK_OVERFLOW_uint64_SUB(symbol_c *res, symbol_c *a, symbol_c *b) { |
218 static void CHECK_OVERFLOW_uint64_SUB(symbol_c *res, symbol_c *a, symbol_c *b) { |
210 if (VALID_CVALUE(uint64, res)) |
219 if (!VALID_CVALUE(uint64, res)) |
211 /* If diference is larger than a => overflow! */ |
220 return; |
212 if (GET_CVALUE(uint64, res) > GET_CVALUE(uint64, a)) |
221 /* Test by post-condition: If diference is larger than a => overflow! */ |
213 SET_OVFLOW(uint64, res); |
222 // if (GET_CVALUE(uint64, res) > GET_CVALUE(uint64, a)) |
214 } |
223 /* Test by pre-condition: if b > a => overflow! */ |
|
224 if (GET_CVALUE(uint64, b) > GET_CVALUE(uint64, a)) |
|
225 SET_OVFLOW(uint64, res); |
|
226 } |
|
227 |
215 |
228 |
216 /* res = a * b */ |
229 /* res = a * b */ |
217 static void CHECK_OVERFLOW_uint64_MUL(symbol_c *res, symbol_c *a, symbol_c *b) { |
230 static void CHECK_OVERFLOW_uint64_MUL(symbol_c *res, symbol_c *a, symbol_c *b) { |
218 if (VALID_CVALUE(uint64, res)) |
231 if (!VALID_CVALUE(uint64, res)) |
219 if (false /* TODO */) |
232 return; |
220 SET_OVFLOW(uint64, res); |
233 /* Test by pre-condition: If (UINT64_MAX / a) < b => overflow! */ |
221 } |
234 if ((UINT64_MAX / GET_CVALUE(uint64, a)) < GET_CVALUE(uint64, b)) |
|
235 SET_OVFLOW(uint64, res); |
|
236 } |
|
237 |
222 |
238 |
223 /* res = a / b */ |
239 /* res = a / b */ |
224 static void CHECK_OVERFLOW_uint64_DIV(symbol_c *res, symbol_c *a, symbol_c *b) { |
240 static void CHECK_OVERFLOW_uint64_DIV(symbol_c *res, symbol_c *a, symbol_c *b) { |
225 if (VALID_CVALUE(uint64, res)) |
241 if (!VALID_CVALUE(uint64, res)) |
226 if (false /* TODO */) |
242 return; |
227 SET_OVFLOW(uint64, res); |
243 if (GET_CVALUE(uint64, b) == 0) /* division by zero! */ |
228 } |
244 SET_OVFLOW(uint64, res); |
|
245 } |
|
246 |
229 |
247 |
230 /* res = a MOD b */ |
248 /* res = a MOD b */ |
231 static void CHECK_OVERFLOW_uint64_MOD(symbol_c *res, symbol_c *a, symbol_c *b) { |
249 static void CHECK_OVERFLOW_uint64_MOD(symbol_c *res, symbol_c *a, symbol_c *b) { |
232 if (VALID_CVALUE(uint64, res)) |
250 if (!VALID_CVALUE(uint64, res)) |
233 if (false /* TODO */) |
251 return; |
234 SET_OVFLOW(uint64, res); |
252 /* no overflow condition exists, including division by zero, which IEC 61131-3 considers legal for MOD operation! */ |
235 } |
253 if (false) |
|
254 SET_OVFLOW(uint64, res); |
|
255 } |
|
256 |
236 |
257 |
237 /* res = a + b */ |
258 /* res = a + b */ |
238 static void CHECK_OVERFLOW_int64_SUM(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
259 static void CHECK_OVERFLOW_int64_SUM(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
|
260 if (!VALID_CVALUE(int64, res)) |
|
261 return; |
239 int64_t a = GET_CVALUE(int64, a_ptr); |
262 int64_t a = GET_CVALUE(int64, a_ptr); |
240 int64_t b = GET_CVALUE(int64, b_ptr); |
263 int64_t b = GET_CVALUE(int64, b_ptr); |
241 if (VALID_CVALUE(int64, res)) |
264 /* The following test is valid no matter what representation is being used (e.g. two's complement, etc...) */ |
242 /* The following test is valid no matter what representation is being used (e.g. two's complement, etc...) */ |
265 if (((b > 0) && (a > (INT64_MAX - b))) |
243 if (((b > 0) && (a > (INT64_MAX - b))) |
266 || ((b < 0) && (a < (INT64_MIN - b)))) |
244 || ((b < 0) && (a < (INT64_MIN - b)))) |
267 SET_OVFLOW(int64, res); |
245 SET_OVFLOW(int64, res); |
268 } |
246 } |
269 |
247 |
270 |
248 /* res = a - b */ |
271 /* res = a - b */ |
249 static void CHECK_OVERFLOW_int64_SUB(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
272 static void CHECK_OVERFLOW_int64_SUB(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
|
273 if (!VALID_CVALUE(int64, res)) |
|
274 return; |
250 int64_t a = GET_CVALUE(int64, a_ptr); |
275 int64_t a = GET_CVALUE(int64, a_ptr); |
251 int64_t b = GET_CVALUE(int64, b_ptr); |
276 int64_t b = GET_CVALUE(int64, b_ptr); |
252 if (VALID_CVALUE(int64, res)) |
277 /* The following test is valid no matter what representation is being used (e.g. two's complement, etc...) */ |
253 /* The following test is valid no matter what representation is being used (e.g. two's complement, etc...) */ |
278 if (((b > 0) && (a < (INT64_MIN + b))) |
254 if (((b > 0) && (a < (INT64_MIN + b))) |
279 || ((b < 0) && (a > (INT64_MAX + b)))) |
255 || ((b < 0) && (a > (INT64_MAX + b)))) |
280 SET_OVFLOW(int64, res); |
256 SET_OVFLOW(int64, res); |
|
257 } |
281 } |
258 |
282 |
259 |
283 |
260 /* res = a * b */ |
284 /* res = a * b */ |
261 static void CHECK_OVERFLOW_int64_MUL(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
285 static void CHECK_OVERFLOW_int64_MUL(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
|
286 if (!VALID_CVALUE(int64, res)) |
|
287 return; |
262 int64_t a = GET_CVALUE(int64, a_ptr); |
288 int64_t a = GET_CVALUE(int64, a_ptr); |
263 int64_t b = GET_CVALUE(int64, b_ptr); |
289 int64_t b = GET_CVALUE(int64, b_ptr); |
264 if (VALID_CVALUE(int64, res)) |
290 if ( ( (a > 0) && (b > 0) && (a > (INT64_MAX / b))) |
265 if ( ( (a > 0) && (b > 0) && (a > (INT64_MAX / b))) |
291 || ( (a > 0) && !(b > 0) && (b < (INT64_MIN / a))) |
266 || ( (a > 0) && !(b > 0) && (b < (INT64_MIN / a))) |
292 || (!(a > 0) && (b > 0) && (a < (INT64_MIN / b))) |
267 || (!(a > 0) && (b > 0) && (a < (INT64_MIN / b))) |
293 || (!(a > 0) && !(b > 0) && (a != 0) && (b < (INT64_MAX / a)))) |
268 || (!(a > 0) && !(b > 0) && (a != 0) && (b < (INT64_MAX / a)))) |
294 SET_OVFLOW(int64, res); |
269 SET_OVFLOW(int64, res); |
|
270 } |
295 } |
271 |
296 |
272 |
297 |
273 /* res = a / b */ |
298 /* res = a / b */ |
274 static void CHECK_OVERFLOW_int64_DIV(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
299 static void CHECK_OVERFLOW_int64_DIV(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
|
300 if (!VALID_CVALUE(int64, res)) |
|
301 return; |
275 int64_t a = GET_CVALUE(int64, a_ptr); |
302 int64_t a = GET_CVALUE(int64, a_ptr); |
276 int64_t b = GET_CVALUE(int64, b_ptr); |
303 int64_t b = GET_CVALUE(int64, b_ptr); |
277 if (VALID_CVALUE(int64, res)) |
304 if ((b == 0) || ((a == INT64_MIN) && (b == -1))) |
278 if ((b == 0) || ((a == INT64_MIN) && (b == -1))) |
305 SET_OVFLOW(int64, res); |
279 SET_OVFLOW(int64, res); |
|
280 } |
306 } |
281 |
307 |
282 |
308 |
283 /* res = a MOD b */ |
309 /* res = a MOD b */ |
284 static void CHECK_OVERFLOW_int64_MOD(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
310 static void CHECK_OVERFLOW_int64_MOD(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
|
311 if (!VALID_CVALUE(int64, res)) |
|
312 return; |
285 int64_t a = GET_CVALUE(int64, a_ptr); |
313 int64_t a = GET_CVALUE(int64, a_ptr); |
286 int64_t b = GET_CVALUE(int64, b_ptr); |
314 int64_t b = GET_CVALUE(int64, b_ptr); |
287 /* IEC 61131-3 standard says IN1 MOD IN2 must be equivalent to |
315 /* IEC 61131-3 standard says IN1 MOD IN2 must be equivalent to |
288 * IF (IN2 = 0) THEN OUT:=0 ; ELSE OUT:=IN1 - (IN1/IN2)*IN2 ; END_IF |
316 * IF (IN2 = 0) THEN OUT:=0 ; ELSE OUT:=IN1 - (IN1/IN2)*IN2 ; END_IF |
289 * |
317 * |
290 * Note that, when IN1 = INT64_MIN, and IN2 = -1, an overflow occurs in the division, |
318 * Note that, when IN1 = INT64_MIN, and IN2 = -1, an overflow occurs in the division, |
291 * so although the MOD operation should be OK, acording to the above definition, we actually have an overflow!! |
319 * so although the MOD operation should be OK, acording to the above definition, we actually have an overflow!! |
292 * |
320 * |
293 * On the other hand, division by 0 is OK!! |
321 * On the other hand, division by 0 is OK!! |
294 */ |
322 */ |
295 if (VALID_CVALUE(int64, res)) |
323 if ((a == INT64_MIN) && (b == -1)) |
296 if ((a == INT64_MIN) && (b == -1)) |
324 SET_OVFLOW(int64, res); |
297 SET_OVFLOW(int64, res); |
|
298 } |
325 } |
299 |
326 |
300 |
327 |
301 /* res = - a */ |
328 /* res = - a */ |
302 static void CHECK_OVERFLOW_int64_NEG(symbol_c *res, symbol_c *a_ptr) { |
329 static void CHECK_OVERFLOW_int64_NEG(symbol_c *res, symbol_c *a_ptr) { |
|
330 if (!VALID_CVALUE(int64, res)) |
|
331 return; |
303 int64_t a = GET_CVALUE(int64, a_ptr); |
332 int64_t a = GET_CVALUE(int64, a_ptr); |
304 if (VALID_CVALUE(int64, res)) |
333 if (a == INT64_MIN) |
305 if (a == INT64_MIN) |
334 SET_OVFLOW(int64, res); |
306 SET_OVFLOW(int64, res); |
|
307 } |
335 } |
308 |
336 |
309 |
337 |
310 |
338 |
311 static void CHECK_OVERFLOW_real64(symbol_c *res) { |
339 static void CHECK_OVERFLOW_real64(symbol_c *res) { |
312 if (VALID_CVALUE(real64, res)) |
340 if (!VALID_CVALUE(real64, res)) |
313 /* NaN => underflow, overflow, number is a higher precision format, is a complex number (IEEE standard) */ |
341 return; |
314 if (isnan(GET_CVALUE(real64, res))) |
342 /* NaN => underflow, overflow, number is a higher precision format, is a complex number (IEEE standard) */ |
315 SET_OVFLOW(real64, res); |
343 if (isnan(GET_CVALUE(real64, res))) |
|
344 SET_OVFLOW(real64, res); |
316 } |
345 } |
317 |
346 |
318 |
347 |
319 |
348 |
320 |
349 |
482 /* B 3.1 - Expressions */ |
511 /* B 3.1 - Expressions */ |
483 /***********************/ |
512 /***********************/ |
484 void *constant_folding_c::visit(or_expression_c *symbol) { |
513 void *constant_folding_c::visit(or_expression_c *symbol) { |
485 symbol->l_exp->accept(*this); |
514 symbol->l_exp->accept(*this); |
486 symbol->r_exp->accept(*this); |
515 symbol->r_exp->accept(*this); |
487 DO_BIN_OPER(bool, ||); |
516 DO_BINARY_OPER(bool, ||); |
488 DO_BIN_OPER(uint64, | ); |
517 DO_BINARY_OPER(uint64, | ); |
489 return NULL; |
518 return NULL; |
490 } |
519 } |
491 |
520 |
492 |
521 |
493 void *constant_folding_c::visit(xor_expression_c *symbol) { |
522 void *constant_folding_c::visit(xor_expression_c *symbol) { |
494 symbol->l_exp->accept(*this); |
523 symbol->l_exp->accept(*this); |
495 symbol->r_exp->accept(*this); |
524 symbol->r_exp->accept(*this); |
496 DO_BIN_OPER(bool, ^); |
525 DO_BINARY_OPER(bool, ^); |
497 DO_BIN_OPER(uint64, ^); |
526 DO_BINARY_OPER(uint64, ^); |
498 return NULL; |
527 return NULL; |
499 } |
528 } |
500 |
529 |
501 |
530 |
502 void *constant_folding_c::visit(and_expression_c *symbol) { |
531 void *constant_folding_c::visit(and_expression_c *symbol) { |
503 symbol->l_exp->accept(*this); |
532 symbol->l_exp->accept(*this); |
504 symbol->r_exp->accept(*this); |
533 symbol->r_exp->accept(*this); |
505 DO_BIN_OPER(bool, &&); |
534 DO_BINARY_OPER(bool, &&); |
506 DO_BIN_OPER(uint64, & ); |
535 DO_BINARY_OPER(uint64, & ); |
507 return NULL; |
536 return NULL; |
508 } |
537 } |
509 |
538 |
510 |
539 |
511 void *constant_folding_c::visit(equ_expression_c *symbol) { |
540 void *constant_folding_c::visit(equ_expression_c *symbol) { |
512 symbol->l_exp->accept(*this); |
541 symbol->l_exp->accept(*this); |
513 symbol->r_exp->accept(*this); |
542 symbol->r_exp->accept(*this); |
514 DO_BIN_OPER(bool, ==); |
543 DO_BINARY_OPER(bool, ==); |
515 DO_BIN_OPER(uint64, ==); |
544 DO_BINARY_OPER(uint64, ==); |
516 DO_BIN_OPER( int64, ==); |
545 DO_BINARY_OPER( int64, ==); |
517 DO_BIN_OPER(real64, ==); |
546 DO_BINARY_OPER(real64, ==); |
518 return NULL; |
547 return NULL; |
519 } |
548 } |
520 |
549 |
521 |
550 |
522 void *constant_folding_c::visit(notequ_expression_c *symbol) { |
551 void *constant_folding_c::visit(notequ_expression_c *symbol) { |
523 symbol->l_exp->accept(*this); |
552 symbol->l_exp->accept(*this); |
524 symbol->r_exp->accept(*this); |
553 symbol->r_exp->accept(*this); |
525 DO_BIN_OPER(bool, !=); |
554 DO_BINARY_OPER(bool, !=); |
526 DO_BIN_OPER(uint64, !=); |
555 DO_BINARY_OPER(uint64, !=); |
527 DO_BIN_OPER( int64, !=); |
556 DO_BINARY_OPER( int64, !=); |
528 DO_BIN_OPER(real64, !=); |
557 DO_BINARY_OPER(real64, !=); |
529 return NULL; |
558 return NULL; |
530 } |
559 } |
531 |
560 |
532 |
561 |
533 void *constant_folding_c::visit(lt_expression_c *symbol) { |
562 void *constant_folding_c::visit(lt_expression_c *symbol) { |
534 symbol->l_exp->accept(*this); |
563 symbol->l_exp->accept(*this); |
535 symbol->r_exp->accept(*this); |
564 symbol->r_exp->accept(*this); |
536 DO_BIN_OPER(bool, <); |
565 DO_BINARY_OPER(bool, <); |
537 DO_BIN_OPER(uint64, <); |
566 DO_BINARY_OPER(uint64, <); |
538 DO_BIN_OPER( int64, <); |
567 DO_BINARY_OPER( int64, <); |
539 DO_BIN_OPER(real64, <); |
568 DO_BINARY_OPER(real64, <); |
540 return NULL; |
569 return NULL; |
541 } |
570 } |
542 |
571 |
543 |
572 |
544 void *constant_folding_c::visit(gt_expression_c *symbol) { |
573 void *constant_folding_c::visit(gt_expression_c *symbol) { |
545 symbol->l_exp->accept(*this); |
574 symbol->l_exp->accept(*this); |
546 symbol->r_exp->accept(*this); |
575 symbol->r_exp->accept(*this); |
547 DO_BIN_OPER(bool, >); |
576 DO_BINARY_OPER(bool, >); |
548 DO_BIN_OPER(uint64, >); |
577 DO_BINARY_OPER(uint64, >); |
549 DO_BIN_OPER( int64, >); |
578 DO_BINARY_OPER( int64, >); |
550 DO_BIN_OPER(real64, >); |
579 DO_BINARY_OPER(real64, >); |
551 return NULL; |
580 return NULL; |
552 } |
581 } |
553 |
582 |
554 |
583 |
555 void *constant_folding_c::visit(le_expression_c *symbol) { |
584 void *constant_folding_c::visit(le_expression_c *symbol) { |
556 symbol->l_exp->accept(*this); |
585 symbol->l_exp->accept(*this); |
557 symbol->r_exp->accept(*this); |
586 symbol->r_exp->accept(*this); |
558 DO_BIN_OPER(bool, <=); |
587 DO_BINARY_OPER(bool, <=); |
559 DO_BIN_OPER(uint64, <=); |
588 DO_BINARY_OPER(uint64, <=); |
560 DO_BIN_OPER( int64, <=); |
589 DO_BINARY_OPER( int64, <=); |
561 DO_BIN_OPER(real64, <=); |
590 DO_BINARY_OPER(real64, <=); |
562 return NULL; |
591 return NULL; |
563 } |
592 } |
564 |
593 |
565 |
594 |
566 void *constant_folding_c::visit(ge_expression_c *symbol) { |
595 void *constant_folding_c::visit(ge_expression_c *symbol) { |
567 symbol->l_exp->accept(*this); |
596 symbol->l_exp->accept(*this); |
568 symbol->r_exp->accept(*this); |
597 symbol->r_exp->accept(*this); |
569 DO_BIN_OPER(bool, >=); |
598 DO_BINARY_OPER(bool, >=); |
570 DO_BIN_OPER(uint64, >=); |
599 DO_BINARY_OPER(uint64, >=); |
571 DO_BIN_OPER( int64, >=); |
600 DO_BINARY_OPER( int64, >=); |
572 DO_BIN_OPER(real64, >=); |
601 DO_BINARY_OPER(real64, >=); |
573 return NULL; |
602 return NULL; |
574 } |
603 } |
575 |
604 |
576 |
605 |
577 void *constant_folding_c::visit(add_expression_c *symbol) { |
606 void *constant_folding_c::visit(add_expression_c *symbol) { |
578 symbol->l_exp->accept(*this); |
607 symbol->l_exp->accept(*this); |
579 symbol->r_exp->accept(*this); |
608 symbol->r_exp->accept(*this); |
580 DO_BIN_OPER(uint64, +); CHECK_OVERFLOW_uint64_SUM(symbol, symbol->l_exp, symbol->r_exp); |
609 DO_BINARY_OPER(uint64, +); CHECK_OVERFLOW_uint64_SUM(symbol, symbol->l_exp, symbol->r_exp); |
581 DO_BIN_OPER( int64, +); CHECK_OVERFLOW_int64_SUM (symbol, symbol->l_exp, symbol->r_exp); |
610 DO_BINARY_OPER( int64, +); CHECK_OVERFLOW_int64_SUM (symbol, symbol->l_exp, symbol->r_exp); |
582 DO_BIN_OPER(real64, +); CHECK_OVERFLOW_real64 (symbol); |
611 DO_BINARY_OPER(real64, +); CHECK_OVERFLOW_real64 (symbol); |
583 return NULL; |
612 return NULL; |
584 } |
613 } |
585 |
614 |
586 |
615 |
587 void *constant_folding_c::visit(sub_expression_c *symbol) { |
616 void *constant_folding_c::visit(sub_expression_c *symbol) { |
588 symbol->l_exp->accept(*this); |
617 symbol->l_exp->accept(*this); |
589 symbol->r_exp->accept(*this); |
618 symbol->r_exp->accept(*this); |
590 DO_BIN_OPER(uint64, -); CHECK_OVERFLOW_uint64_SUB(symbol, symbol->l_exp, symbol->r_exp); |
619 DO_BINARY_OPER(uint64, -); CHECK_OVERFLOW_uint64_SUB(symbol, symbol->l_exp, symbol->r_exp); |
591 DO_BIN_OPER( int64, -); CHECK_OVERFLOW_int64_SUB (symbol, symbol->l_exp, symbol->r_exp); |
620 DO_BINARY_OPER( int64, -); CHECK_OVERFLOW_int64_SUB (symbol, symbol->l_exp, symbol->r_exp); |
592 DO_BIN_OPER(real64, -); CHECK_OVERFLOW_real64 (symbol); |
621 DO_BINARY_OPER(real64, -); CHECK_OVERFLOW_real64 (symbol); |
593 return NULL; |
622 return NULL; |
594 } |
623 } |
595 |
624 |
596 |
625 |
597 void *constant_folding_c::visit(mul_expression_c *symbol) { |
626 void *constant_folding_c::visit(mul_expression_c *symbol) { |
598 symbol->l_exp->accept(*this); |
627 symbol->l_exp->accept(*this); |
599 symbol->r_exp->accept(*this); |
628 symbol->r_exp->accept(*this); |
600 DO_BIN_OPER(uint64, *); CHECK_OVERFLOW_uint64_MUL(symbol, symbol->l_exp, symbol->r_exp); |
629 DO_BINARY_OPER(uint64, *); CHECK_OVERFLOW_uint64_MUL(symbol, symbol->l_exp, symbol->r_exp); |
601 DO_BIN_OPER( int64, *); CHECK_OVERFLOW_int64_MUL (symbol, symbol->l_exp, symbol->r_exp); |
630 DO_BINARY_OPER( int64, *); CHECK_OVERFLOW_int64_MUL (symbol, symbol->l_exp, symbol->r_exp); |
602 DO_BIN_OPER(real64, *); CHECK_OVERFLOW_real64 (symbol); |
631 DO_BINARY_OPER(real64, *); CHECK_OVERFLOW_real64 (symbol); |
603 return NULL; |
632 return NULL; |
604 } |
633 } |
605 |
634 |
606 |
635 |
607 |
636 |
608 void *constant_folding_c::visit(div_expression_c *symbol) { |
637 void *constant_folding_c::visit(div_expression_c *symbol) { |
609 symbol->l_exp->accept(*this); |
638 symbol->l_exp->accept(*this); |
610 symbol->r_exp->accept(*this); |
639 symbol->r_exp->accept(*this); |
611 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);}; |
640 if (ISZERO_CVALUE(uint64, symbol->r_exp)) {NEW_CVALUE(uint64, symbol); SET_OVFLOW(uint64, symbol);} else {DO_BINARY_OPER(uint64, /); CHECK_OVERFLOW_uint64_DIV(symbol, symbol->l_exp, symbol->r_exp);}; |
612 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);}; |
641 if (ISZERO_CVALUE( int64, symbol->r_exp)) {NEW_CVALUE( int64, symbol); SET_OVFLOW( int64, symbol);} else {DO_BINARY_OPER( int64, /); CHECK_OVERFLOW_int64_DIV(symbol, symbol->l_exp, symbol->r_exp);}; |
613 if (ISZERO_CVALUE(real64, symbol->r_exp)) {NEW_CVALUE(real64, symbol); SET_OVFLOW(real64, symbol);} else {DO_BIN_OPER(real64, /); CHECK_OVERFLOW_real64(symbol);}; |
642 if (ISZERO_CVALUE(real64, symbol->r_exp)) {NEW_CVALUE(real64, symbol); SET_OVFLOW(real64, symbol);} else {DO_BINARY_OPER(real64, /); CHECK_OVERFLOW_real64(symbol);}; |
614 return NULL; |
643 return NULL; |
615 } |
644 } |
616 |
645 |
617 |
646 |
618 void *constant_folding_c::visit(mod_expression_c *symbol) { |
647 void *constant_folding_c::visit(mod_expression_c *symbol) { |