|
18 | 18 | #include <util/base_type.h>
|
19 | 19 | #include <util/cprover_prefix.h>
|
20 | 20 | #include <util/c_types.h>
|
| 21 | +#include <util/config.h> |
21 | 22 | #include <util/expr_util.h>
|
22 | 23 | #include <util/find_symbols.h>
|
23 | 24 | #include <util/guard.h>
|
@@ -634,12 +635,38 @@ void goto_checkt::integer_overflow_check(
|
634 | 635 |
|
635 | 636 | const exprt op_ext_shifted = shl_exprt(op_ext, distance);
|
636 | 637 |
|
637 |
| - // get top bits of the shifted operand |
| 638 | + // The semantics of signed left shifts are contentious for the case |
| 639 | + // that a '1' is shifted into the signed bit. |
| 640 | + // Assuming 32-bit integers, 1<<31 is implementation-defined |
| 641 | + // in ANSI C and C++98, but is explicitly undefined by C99, |
| 642 | + // C11 and C++11. |
| 643 | + bool allow_shift_into_sign_bit = true; |
| 644 | + |
| 645 | + if(mode == ID_C) |
| 646 | + { |
| 647 | + if(config.ansi_c.c_standard == configt::ansi_ct::c_standardt::C99 || |
| 648 | + config.ansi_c.c_standard == configt::ansi_ct::c_standardt::C11) |
| 649 | + { |
| 650 | + allow_shift_into_sign_bit = false; |
| 651 | + } |
| 652 | + } |
| 653 | + else if(mode == ID_cpp) |
| 654 | + { |
| 655 | + if(config.cpp.cpp_standard == configt::cppt::cpp_standardt::CPP11 || |
| 656 | + config.cpp.cpp_standard == configt::cppt::cpp_standardt::CPP14) |
| 657 | + { |
| 658 | + allow_shift_into_sign_bit = false; |
| 659 | + } |
| 660 | + } |
| 661 | + |
| 662 | + const unsigned number_of_top_bits = |
| 663 | + allow_shift_into_sign_bit ? op_width : op_width + 1; |
| 664 | + |
638 | 665 | const exprt top_bits = extractbits_exprt(
|
639 | 666 | op_ext_shifted,
|
640 | 667 | new_type.get_width() - 1,
|
641 |
| - op_width - 1, |
642 |
| - unsignedbv_typet(op_width + 1)); |
| 668 | + new_type.get_width() - number_of_top_bits, |
| 669 | + unsignedbv_typet(number_of_top_bits)); |
643 | 670 |
|
644 | 671 | const exprt top_bits_zero =
|
645 | 672 | equal_exprt(top_bits, from_integer(0, top_bits.type()));
|
|
0 commit comments