1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
/*******************************************************************\
Module: Unit tests of expression size/offset computation
Author: Michael Tautschnig
\*******************************************************************/
#include <testing-utils/use_catch.h>
#include <util/arith_tools.h>
#include <util/byte_operators.h>
#include <util/c_types.h>
#include <util/cmdline.h>
#include <util/config.h>
#include <util/namespace.h>
#include <util/pointer_offset_size.h>
#include <util/std_expr.h>
#include <util/symbol_table.h>
TEST_CASE("Build subexpression to access element at offset into array")
{
// this test does require a proper architecture to be set so that byte extract
// uses adequate endianness
cmdlinet cmdline;
config.set(cmdline);
symbol_tablet symbol_table;
namespacet ns(symbol_table);
const signedbv_typet t(32);
array_typet array_type(t, from_integer(2, size_type()));
symbol_exprt a("array", array_type);
{
const auto result = get_subexpression_at_offset(a, 0, t, ns);
REQUIRE(result.value() == index_exprt(a, from_integer(0, c_index_type())));
}
{
const auto result = get_subexpression_at_offset(a, 32 / 8, t, ns);
REQUIRE(result.value() == index_exprt(a, from_integer(1, c_index_type())));
}
{
const auto result =
get_subexpression_at_offset(a, from_integer(0, size_type()), t, ns);
REQUIRE(result.value() == index_exprt(a, from_integer(0, c_index_type())));
}
{
const auto result =
get_subexpression_at_offset(a, size_of_expr(t, ns).value(), t, ns);
REQUIRE(result.value() == index_exprt(a, from_integer(1, c_index_type())));
}
{
const signedbv_typet small_t(8);
const auto result = get_subexpression_at_offset(a, 1, small_t, ns);
REQUIRE(
result.value() == make_byte_extract(
index_exprt(a, from_integer(0, c_index_type())),
from_integer(1, c_index_type()),
small_t));
}
{
const signedbv_typet int16_t(16);
const auto result = get_subexpression_at_offset(a, 3, int16_t, ns);
// At offset 3 there are only 8 bits remaining in an element of type t so
// not enough to fill a 16 bit int, so this cannot be transformed in an
// index_exprt.
REQUIRE(
result.value() ==
make_byte_extract(a, from_integer(3, c_index_type()), int16_t));
}
}
TEST_CASE("Build subexpression to access element at offset into struct")
{
// this test does require a proper architecture to be set so that byte extract
// uses adequate endianness
cmdlinet cmdline;
config.set(cmdline);
symbol_tablet symbol_table;
namespacet ns(symbol_table);
const signedbv_typet t(32);
struct_typet st({{"foo", t}, {"bar", t}});
symbol_exprt s("struct", st);
{
const auto result = get_subexpression_at_offset(s, 0, t, ns);
REQUIRE(result.value() == member_exprt(s, "foo", t));
}
{
const auto result = get_subexpression_at_offset(s, 32 / 8, t, ns);
REQUIRE(result.value() == member_exprt(s, "bar", t));
}
{
const auto result =
get_subexpression_at_offset(s, from_integer(0, size_type()), t, ns);
REQUIRE(result.value() == member_exprt(s, "foo", t));
}
{
const auto result =
get_subexpression_at_offset(s, size_of_expr(t, ns).value(), t, ns);
REQUIRE(result.value() == member_exprt(s, "bar", t));
}
{
const signedbv_typet small_t(8);
const auto result = get_subexpression_at_offset(s, 1, small_t, ns);
REQUIRE(
result.value() ==
make_byte_extract(
member_exprt(s, "foo", t), from_integer(1, c_index_type()), small_t));
}
}
|