Skip to content

Commit 394cbc7

Browse files
committed
introduce __CPROVER_separate
This introduces C syntax for a multi-ary predicate that implies that the given pointers point to pairwise different objects.
1 parent e7dafeb commit 394cbc7

File tree

5 files changed

+74
-0
lines changed

5 files changed

+74
-0
lines changed

src/ansi-c/c_typecheck_expr.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2536,6 +2536,23 @@ exprt c_typecheck_baset::do_special_functions(
25362536

25372537
return writeable_object_expr;
25382538
}
2539+
else if(identifier == CPROVER_PREFIX "separate")
2540+
{
2541+
// experimental feature for CHC encodings -- do not use
2542+
if(expr.arguments().size() < 2)
2543+
{
2544+
error().source_location = f_op.source_location();
2545+
error() << "separate expects two or more arguments" << eom;
2546+
throw 0;
2547+
}
2548+
2549+
typecheck_function_call_arguments(expr);
2550+
2551+
exprt separate_expr = separate_exprt(expr.arguments());
2552+
separate_expr.add_source_location() = source_location;
2553+
2554+
return separate_expr;
2555+
}
25392556
else if(identifier==CPROVER_PREFIX "POINTER_OFFSET")
25402557
{
25412558
if(expr.arguments().size()!=1)

src/ansi-c/cprover_builtin_headers.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ __CPROVER_bool __CPROVER_is_cyclic_dll();
2323
__CPROVER_bool __CPROVER_is_sentinel_dll();
2424
__CPROVER_bool __CPROVER_is_cstring(const char *);
2525
__CPROVER_size_t __CPROVER_cstrlen(const char *);
26+
__CPROVER_bool __CPROVER_separate(const void *, const void *, ...);
2627

2728
// bitvector analysis
2829
__CPROVER_bool __CPROVER_get_flag(const void *, const char *);
@@ -56,6 +57,8 @@ __CPROVER_size_t __CPROVER_POINTER_OBJECT(const void *);
5657
__CPROVER_ssize_t __CPROVER_POINTER_OFFSET(const void *);
5758
__CPROVER_size_t __CPROVER_OBJECT_SIZE(const void *);
5859
__CPROVER_bool __CPROVER_DYNAMIC_OBJECT(const void *);
60+
__CPROVER_bool __CPROVER_separate(const void *, const void *, ...);
61+
__CPROVER_bool __CPROVER_pointer_in_range(const void *, const void *, const void *);
5962
void __CPROVER_allocated_memory(__CPROVER_size_t address, __CPROVER_size_t extent);
6063

6164
// float stuff

src/ansi-c/expr2c.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3987,6 +3987,7 @@ optionalt<std::string> expr2ct::convert_function(const exprt &src)
39873987
{ID_dynamic_object, "DYNAMIC_OBJECT"},
39883988
{ID_live_object, "LIVE_OBJECT"},
39893989
{ID_writeable_object, "WRITEABLE_OBJECT"},
3990+
{ID_separate, "SEPARATE"},
39903991
{ID_floatbv_div, "FLOAT/"},
39913992
{ID_floatbv_minus, "FLOAT-"},
39923993
{ID_floatbv_mult, "FLOAT*"},

src/util/irep_ids.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@ IREP_ID_ONE(is_dynamic_object)
456456
IREP_ID_ONE(dynamic_object)
457457
IREP_ID_TWO(C_dynamic, #dynamic)
458458
IREP_ID_ONE(object_size)
459+
IREP_ID_ONE(separate)
459460
IREP_ID_ONE(good_pointer)
460461
IREP_ID_ONE(live_object)
461462
IREP_ID_ONE(writeable_object)

src/util/pointer_expr.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,4 +1287,56 @@ inline writeable_object_exprt &to_writeable_object_expr(exprt &expr)
12871287
return ret;
12881288
}
12891289

1290+
/// A predicate that indicates that the objects pointed to are distinct
1291+
class separate_exprt : public multi_ary_exprt
1292+
{
1293+
public:
1294+
explicit separate_exprt(exprt::operandst __operands)
1295+
: multi_ary_exprt(ID_separate, std::move(__operands), bool_typet())
1296+
{
1297+
}
1298+
1299+
separate_exprt(exprt __op0, exprt __op1)
1300+
: multi_ary_exprt(
1301+
std::move(__op0),
1302+
ID_separate,
1303+
std::move(__op1),
1304+
bool_typet())
1305+
{
1306+
}
1307+
};
1308+
1309+
template <>
1310+
inline bool can_cast_expr<separate_exprt>(const exprt &base)
1311+
{
1312+
return base.id() == ID_separate;
1313+
}
1314+
1315+
inline void validate_expr(const separate_exprt &value)
1316+
{
1317+
}
1318+
1319+
/// \brief Cast an exprt to a \ref separate_exprt
1320+
///
1321+
/// \a expr must be known to be \ref separate_exprt.
1322+
///
1323+
/// \param expr: Source expression
1324+
/// \return Object of type \ref separate_exprt
1325+
inline const separate_exprt &to_separate_expr(const exprt &expr)
1326+
{
1327+
PRECONDITION(expr.id() == ID_separate);
1328+
const separate_exprt &ret = static_cast<const separate_exprt &>(expr);
1329+
validate_expr(ret);
1330+
return ret;
1331+
}
1332+
1333+
/// \copydoc to_separate_expr(const exprt &)
1334+
inline separate_exprt &to_separate_expr(exprt &expr)
1335+
{
1336+
PRECONDITION(expr.id() == ID_separate);
1337+
separate_exprt &ret = static_cast<separate_exprt &>(expr);
1338+
validate_expr(ret);
1339+
return ret;
1340+
}
1341+
12901342
#endif // CPROVER_UTIL_POINTER_EXPR_H

0 commit comments

Comments
 (0)