Skip to content

Commit ca64bbc

Browse files
tautschnigDaniel Kroening
authored andcommitted
C++: Add support for indexed access to bitvectors
As a non-standard extension, we permit indexed access to bitvectors. This translates to bit-level updates, which the typechecker now generates.
1 parent 335d9b5 commit ca64bbc

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

regression/systemc/BitvectorCpp2/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ int main(int argc, char** argv)
55
__CPROVER::signedbv<4> x(15);
66
__CPROVER::signedbv<4> y;
77
y = 13;
8-
x[1] = 0; //TODO: currently not supported
8+
x[1] = 0;
99
assert(x == y);
1010

1111
return 0;

regression/systemc/BitvectorCpp2/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.cpp
33

44
^EXIT=0$

src/cpp/cpp_typecheck_code.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Author: Daniel Kroening, [email protected]
1111

1212
#include "cpp_typecheck.h"
1313

14+
#include <util/arith_tools.h>
1415
#include <util/source_location.h>
1516

1617
#include "cpp_convert_type.h"
@@ -41,6 +42,40 @@ void cpp_typecheckt::typecheck_code(codet &code)
4142
{
4243
// type checked already
4344
}
45+
else if(statement == ID_expression)
46+
{
47+
if(
48+
!code.has_operands() || code.op0().id() != ID_side_effect ||
49+
to_side_effect_expr(code.op0()).get_statement() != ID_assign)
50+
{
51+
c_typecheck_baset::typecheck_code(code);
52+
return;
53+
}
54+
55+
// as an extension, we support indexed access into signed/unsigned
56+
// bitvectors, typically used with __CPROVER::(un)signedbv<N>
57+
exprt &expr = code.op0();
58+
if(
59+
expr.operands().size() == 2 && expr.op0().id() == ID_index &&
60+
expr.op0().operands().size() == 2)
61+
{
62+
exprt array = expr.op0().op0();
63+
typecheck_expr(array);
64+
65+
if(array.type().id() == ID_signedbv || array.type().id() == ID_unsignedbv)
66+
{
67+
shl_exprt shl{from_integer(1, array.type()), expr.op0().op1()};
68+
exprt rhs =
69+
if_exprt{equal_exprt{expr.op1(), from_integer(0, array.type())},
70+
bitand_exprt{array, bitnot_exprt{shl}},
71+
bitor_exprt{array, shl}};
72+
expr.op0() = expr.op0().op0();
73+
expr.op1() = rhs;
74+
}
75+
}
76+
77+
c_typecheck_baset::typecheck_code(code);
78+
}
4479
else
4580
c_typecheck_baset::typecheck_code(code);
4681
}

0 commit comments

Comments
 (0)