Skip to content

Commit

Permalink
Shifts of non-integers and left shifts of negative integers are undef…
Browse files Browse the repository at this point in the history
…ined

6.5.7 of C11: "Each of the operands shall have integer type."

Paragraph 4: "If E1 has a signed type and nonnegative value, and E1 x 2^E2 is
representable in the result type, then that is the resulting value; otherwise,
the behavior is undefined."
  • Loading branch information
tautschnig committed Oct 26, 2017
1 parent 6bb3872 commit 1e3712c
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
11 changes: 11 additions & 0 deletions regression/cbmc/Undefined_Shift1/main.c
Original file line number Diff line number Diff line change
@@ -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;
}
9 changes: 9 additions & 0 deletions regression/cbmc/Undefined_Shift1/test.desc
Original file line number Diff line number Diff line change
@@ -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
24 changes: 24 additions & 0 deletions src/analyses/goto_check.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down

0 comments on commit 1e3712c

Please sign in to comment.