diff --git a/regression/cbmc/Overflow_Leftshift1/main.c b/regression/cbmc/Overflow_Leftshift1/main.c new file mode 100644 index 00000000000..70dd6e5c478 --- /dev/null +++ b/regression/cbmc/Overflow_Leftshift1/main.c @@ -0,0 +1,11 @@ +int main() +{ + unsigned char x; + unsigned r=x << ((sizeof(unsigned)-1)*8); + r=x << ((sizeof(unsigned)-1)*8-1); + r=(unsigned)x << ((sizeof(unsigned)-1)*8); + + int s=-1 << ((sizeof(int)-1)*8); + s=-256 << ((sizeof(int)-1)*8); + return 0; +} diff --git a/regression/cbmc/Overflow_Leftshift1/test.desc b/regression/cbmc/Overflow_Leftshift1/test.desc new file mode 100644 index 00000000000..04360e32357 --- /dev/null +++ b/regression/cbmc/Overflow_Leftshift1/test.desc @@ -0,0 +1,9 @@ +CORE +main.c +--signed-overflow-check +^SIGNAL=0$ +^\[.*\] arithmetic overflow on signed shl in .*: FAILURE$ +^\*\* 2 of 4 failed +^VERIFICATION FAILED$ +-- +^warning: ignoring diff --git a/src/analyses/goto_check.cpp b/src/analyses/goto_check.cpp index 95345814426..ffb8cd255b1 100644 --- a/src/analyses/goto_check.cpp +++ b/src/analyses/goto_check.cpp @@ -1418,6 +1418,9 @@ void goto_checkt::check_rec( else if(expr.id()==ID_shl || expr.id()==ID_ashr || expr.id()==ID_lshr) { undefined_shift_check(to_shift_expr(expr), guard); + + if(expr.id()==ID_shl && expr.type().id()==ID_signedbv) + integer_overflow_check(expr, guard); } else if(expr.id()==ID_mod) { diff --git a/src/solvers/flattening/boolbv_overflow.cpp b/src/solvers/flattening/boolbv_overflow.cpp index 33dd61bca33..ceef7d19f0d 100644 --- a/src/solvers/flattening/boolbv_overflow.cpp +++ b/src/solvers/flattening/boolbv_overflow.cpp @@ -8,8 +8,7 @@ Author: Daniel Kroening, kroening@kroening.com #include "boolbv.h" -#include - +#include #include #include @@ -59,7 +58,7 @@ literalt boolbvt::convert_overflow(const exprt &expr) if(operands[0].type()!=operands[1].type()) throw "operand type mismatch on overflow-*"; - assert(bv0.size()==bv1.size()); + DATA_INVARIANT(bv0.size()==bv1.size(), "operands size mismatch"); std::size_t old_size=bv0.size(); std::size_t new_size=old_size*2; @@ -86,7 +85,7 @@ literalt boolbvt::convert_overflow(const exprt &expr) bv_overflow.reserve(old_size); // get top result bits, plus one more - assert(old_size!=0); + DATA_INVARIANT(old_size!=0, "zero-size operand"); for(std::size_t i=old_size-1; i