Skip to content

Commit 4cb3bff

Browse files
committed
Add is_dynamic to object map
So that the information is available in subsequent conversions.
1 parent e52f05d commit 4cb3bff

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

src/solvers/smt2_incremental/object_tracking.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#include <util/arith_tools.h>
66
#include <util/c_types.h>
77
#include <util/pointer_offset_size.h>
8+
#include <util/pointer_predicates.h>
9+
#include <util/prefix.h>
810
#include <util/std_code.h>
911
#include <util/std_expr.h>
1012
#include <util/string_constant.h>
@@ -77,6 +79,21 @@ smt_object_mapt initial_smt_object_map()
7779
return object_map;
7880
}
7981

82+
/// This function returns true for heap allocated objects or false for stack
83+
/// allocated objects.
84+
static bool is_dynamic(const exprt &object)
85+
{
86+
// This check corresponds to the symbols created in
87+
// `goto_symext::symex_allocate`, which implements the `__CPROVER_allocate`
88+
// intrinsic function used by the standard library models.
89+
bool dynamic_type = object.type().get_bool(ID_C_dynamic);
90+
const auto symbol = expr_try_dynamic_cast<symbol_exprt>(object);
91+
bool symbol_is_dynamic =
92+
symbol &&
93+
has_prefix(id2string(symbol->get_identifier()), SYMEX_DYNAMIC_PREFIX);
94+
return dynamic_type || symbol_is_dynamic;
95+
}
96+
8097
void track_expression_objects(
8198
const exprt &expression,
8299
const namespacet &ns,
@@ -93,6 +110,7 @@ void track_expression_objects(
93110
object.base_expression = object_base;
94111
object.unique_id = object_map.size();
95112
object.size = *size;
113+
object.is_dynamic = is_dynamic(object_base);
96114
object_map.emplace_hint(find_result, object_base, std::move(object));
97115
});
98116
}

src/solvers/smt2_incremental/object_tracking.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ struct decision_procedure_objectt
4646
std::size_t unique_id;
4747
/// Expression which evaluates to the size of the object in bytes.
4848
exprt size;
49+
/// This is true for heap allocated objects and false for stack allocated.
50+
bool is_dynamic;
4951
};
5052

5153
/// The model of addresses we use consists of a unique object identifier and an

unit/solvers/smt2_incremental/object_tracking.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <util/c_types.h>
55
#include <util/config.h>
66
#include <util/namespace.h>
7+
#include <util/pointer_predicates.h>
78
#include <util/std_expr.h>
89
#include <util/symbol_table.h>
910

@@ -199,3 +200,32 @@ TEST_CASE("Tracking object sizes.", "[core][smt2_incremental]")
199200
REQUIRE(object != object_map.end());
200201
REQUIRE(object->second.size == expected_size);
201202
}
203+
204+
static typet make_type_dynamic(typet base_type)
205+
{
206+
base_type.set(ID_C_dynamic, true);
207+
return base_type;
208+
}
209+
210+
TEST_CASE("Tracking dynamic object status.", "[core][smt2_incremental]")
211+
{
212+
config.ansi_c.mode = configt::ansi_ct::flavourt::GCC;
213+
config.ansi_c.set_arch_spec_x86_64();
214+
smt_object_mapt object_map = initial_smt_object_map();
215+
symbol_tablet symbol_table;
216+
namespacet ns{symbol_table};
217+
exprt base_object;
218+
bool expected_dynamic_status;
219+
using rowt =
220+
std::pair<decltype(base_object), decltype(expected_dynamic_status)>;
221+
std::tie(base_object, expected_dynamic_status) = GENERATE_REF(
222+
rowt{from_integer(0, unsignedbv_typet{(8)}), false},
223+
rowt{symbol_exprt{"foo", bool_typet{}}, false},
224+
rowt{symbol_exprt{SYMEX_DYNAMIC_PREFIX "bar", bool_typet{}}, true},
225+
rowt{from_integer(42, make_type_dynamic(signedbv_typet{16})), true});
226+
INFO("base_object is - " + base_object.pretty(1, 0));
227+
track_expression_objects(address_of_exprt{base_object}, ns, object_map);
228+
const auto object = object_map.find(base_object);
229+
REQUIRE(object != object_map.end());
230+
REQUIRE(object->second.is_dynamic == expected_dynamic_status);
231+
}

0 commit comments

Comments
 (0)