diff --git a/regression/cbmc/Undefined_Shift1/main.c b/regression/cbmc/Undefined_Shift1/main.c new file mode 100644 index 00000000000..70dd6e5c478 --- /dev/null +++ b/regression/cbmc/Undefined_Shift1/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/Undefined_Shift1/test.desc b/regression/cbmc/Undefined_Shift1/test.desc new file mode 100644 index 00000000000..e82c3b92690 --- /dev/null +++ b/regression/cbmc/Undefined_Shift1/test.desc @@ -0,0 +1,9 @@ +CORE +main.c +--undefined-shift-check +^SIGNAL=0$ +^\[.*\] shift operand is negative in .*: FAILURE$ +^\*\* 1 of 2 failed +^VERIFICATION FAILED$ +-- +^warning: ignoring diff --git a/src/analyses/goto_check.cpp b/src/analyses/goto_check.cpp index ffb8cd255b1..c36c8b189dc 100644 --- a/src/analyses/goto_check.cpp +++ b/src/analyses/goto_check.cpp @@ -286,6 +286,30 @@ void goto_checkt::undefined_shift_check( expr.find_source_location(), expr, guard); + + if(op_type.id()==ID_signedbv && expr.id()==ID_shl) + { + binary_relation_exprt inequality( + expr.op(), ID_ge, from_integer(0, op_type)); + + add_guarded_claim( + inequality, + "shift operand is negative", + "undefined-shift", + expr.find_source_location(), + expr, + guard); + } + } + else + { + add_guarded_claim( + false_exprt(), + "shift of non-integer type", + "undefined-shift", + expr.find_source_location(), + expr, + guard); } }