Skip to content

Commit a57d53c

Browse files
authored
Merge pull request diffblue#4021 from smowton/smowton/feature/verify-member-expressions
Verify member expressions [blocks: diffblue#4023]
2 parents 0b58dc5 + 44756ee commit a57d53c

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

src/util/std_expr.cpp

+41
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Author: Daniel Kroening, [email protected]
1515
#include "c_types.h"
1616
#include "expr_util.h"
1717
#include "mathematical_types.h"
18+
#include "namespace.h"
1819
#include "pointer_offset_size.h"
1920
#include "simplify_expr.h"
2021

@@ -226,3 +227,43 @@ const exprt &object_descriptor_exprt::root_object() const
226227

227228
return *p;
228229
}
230+
231+
/// Check that the member expression has the right number of operands, refers
232+
/// to a component that exists on its underlying compound type, and uses the
233+
/// same type as is declared on that compound type. Throws or raises an
234+
/// invariant if not, according to validation mode.
235+
/// \param expr: expression to validate
236+
/// \param ns: global namespace
237+
/// \param vm: validation mode (see \ref exprt::validate)
238+
void member_exprt::validate(
239+
const exprt &expr,
240+
const namespacet &ns,
241+
const validation_modet vm)
242+
{
243+
check(expr, vm);
244+
245+
const auto &member_expr = to_member_expr(expr);
246+
247+
const typet &compound_type = ns.follow(member_expr.compound().type());
248+
const auto *struct_union_type =
249+
type_try_dynamic_cast<struct_union_typet>(compound_type);
250+
DATA_CHECK(
251+
vm,
252+
struct_union_type != nullptr,
253+
"member must address a struct, union or compatible type");
254+
255+
const auto &component =
256+
struct_union_type->get_component(member_expr.get_component_name());
257+
258+
DATA_CHECK(
259+
vm,
260+
component.is_not_nil(),
261+
"member component '" + id2string(member_expr.get_component_name()) +
262+
"' must exist on addressed type");
263+
264+
DATA_CHECK(
265+
vm,
266+
component.type() == member_expr.type(),
267+
"member expression's type must match the addressed struct or union "
268+
"component");
269+
}

src/util/std_expr.h

+15
Original file line numberDiff line numberDiff line change
@@ -3795,6 +3795,21 @@ class member_exprt:public unary_exprt
37953795
{
37963796
return op0();
37973797
}
3798+
3799+
static void check(
3800+
const exprt &expr,
3801+
const validation_modet vm = validation_modet::INVARIANT)
3802+
{
3803+
DATA_CHECK(
3804+
vm,
3805+
expr.operands().size() == 1,
3806+
"member expression must have one operand");
3807+
}
3808+
3809+
static void validate(
3810+
const exprt &expr,
3811+
const namespacet &ns,
3812+
const validation_modet vm = validation_modet::INVARIANT);
37983813
};
37993814

38003815
template <>

src/util/validate_expressions.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ void call_on_expr(const exprt &expr, Args &&... args)
3737
{
3838
CALL_ON_EXPR(ssa_exprt);
3939
}
40+
else if(expr.id() == ID_member)
41+
{
42+
CALL_ON_EXPR(member_exprt);
43+
}
4044
else
4145
{
4246
#ifdef REPORT_UNIMPLEMENTED_EXPRESSION_CHECKS

0 commit comments

Comments
 (0)