@@ -1166,6 +1166,7 @@ void __CPROVER_contracts_make_invalid_pointer(void **ptr)
1166
1166
///
1167
1167
/// \param ptr1 First argument of the `pointer_equals` predicate
1168
1168
/// \param ptr2 Second argument of the `pointer_equals` predicate
1169
+ /// \param may_fail Allow predicate to fail in assume mode
1169
1170
/// \param write_set Write set which conveys the invocation context
1170
1171
/// (requires/ensures clause, assert/assume context);
1171
1172
///
@@ -1179,6 +1180,7 @@ void __CPROVER_contracts_make_invalid_pointer(void **ptr)
1179
1180
__CPROVER_bool __CPROVER_contracts_pointer_equals (
1180
1181
void * * ptr1 ,
1181
1182
void * ptr2 ,
1183
+ __CPROVER_bool may_fail ,
1182
1184
__CPROVER_contracts_write_set_ptr_t write_set )
1183
1185
{
1184
1186
__CPROVER_HIDE :;
@@ -1195,7 +1197,8 @@ __CPROVER_HIDE:;
1195
1197
#endif
1196
1198
if (write_set -> assume_requires_ctx | write_set -> assume_ensures_ctx )
1197
1199
{
1198
- if (__VERIFIER_nondet___CPROVER_bool ())
1200
+ // SOUNDNESS: allow predicate to fail
1201
+ if (may_fail && __VERIFIER_nondet___CPROVER_bool ())
1199
1202
{
1200
1203
__CPROVER_contracts_make_invalid_pointer (ptr1 );
1201
1204
return 0 ;
@@ -1224,8 +1227,9 @@ __CPROVER_HIDE:;
1224
1227
/// The behaviour depends on the boolean flags carried by \p write_set
1225
1228
/// which reflect the invocation context: checking vs. replacing a contract,
1226
1229
/// in a requires or an ensures clause context.
1227
- /// \param elem First argument of the `is_fresh` predicate
1228
- /// \param size Second argument of the `is_fresh` predicate
1230
+ /// \param elem Pointer to the target pointer of the check
1231
+ /// \param size Size to check for
1232
+ /// \param may_fail Allow predicate to fail in assume mode
1229
1233
/// \param write_set Write set in which seen/allocated objects are recorded;
1230
1234
///
1231
1235
/// \details The behaviour is as follows:
@@ -1242,6 +1246,7 @@ __CPROVER_HIDE:;
1242
1246
__CPROVER_bool __CPROVER_contracts_is_fresh (
1243
1247
void * * elem ,
1244
1248
__CPROVER_size_t size ,
1249
+ __CPROVER_bool may_fail ,
1245
1250
__CPROVER_contracts_write_set_ptr_t write_set )
1246
1251
{
1247
1252
__CPROVER_HIDE :;
@@ -1289,7 +1294,7 @@ __CPROVER_HIDE:;
1289
1294
}
1290
1295
1291
1296
// SOUNDNESS: allow predicate to fail
1292
- if (__VERIFIER_nondet___CPROVER_bool ())
1297
+ if (may_fail && __VERIFIER_nondet___CPROVER_bool ())
1293
1298
{
1294
1299
__CPROVER_contracts_make_invalid_pointer (elem );
1295
1300
return 0 ;
@@ -1349,7 +1354,7 @@ __CPROVER_HIDE:;
1349
1354
}
1350
1355
1351
1356
// SOUNDNESS: allow predicate to fail
1352
- if (__VERIFIER_nondet___CPROVER_bool ())
1357
+ if (may_fail && __VERIFIER_nondet___CPROVER_bool ())
1353
1358
{
1354
1359
__CPROVER_contracts_make_invalid_pointer (elem );
1355
1360
return 0 ;
@@ -1436,6 +1441,7 @@ __CPROVER_HIDE:;
1436
1441
/// \param lb Lower bound pointer
1437
1442
/// \param ptr Target pointer of the predicate
1438
1443
/// \param ub Upper bound pointer
1444
+ /// \param may_fail Allow predicate to fail in assume mode
1439
1445
/// \param write_set Write set in which seen/allocated objects are recorded;
1440
1446
///
1441
1447
/// \details The behaviour is as follows:
@@ -1449,6 +1455,7 @@ __CPROVER_bool __CPROVER_contracts_pointer_in_range_dfcc(
1449
1455
void * lb ,
1450
1456
void * * ptr ,
1451
1457
void * ub ,
1458
+ __CPROVER_bool may_fail ,
1452
1459
__CPROVER_contracts_write_set_ptr_t write_set )
1453
1460
{
1454
1461
__CPROVER_HIDE :;
@@ -1470,9 +1477,9 @@ __CPROVER_HIDE:;
1470
1477
lb_offset <= ub_offset , "lb and ub pointers must be ordered" );
1471
1478
if (write_set -> assume_requires_ctx | write_set -> assume_ensures_ctx )
1472
1479
{
1473
- if (__VERIFIER_nondet___CPROVER_bool ())
1480
+ // SOUNDNESS: allow predicate to fail
1481
+ if (may_fail && __VERIFIER_nondet___CPROVER_bool ())
1474
1482
{
1475
- // SOUNDNESS: allow predicate to fail
1476
1483
__CPROVER_contracts_make_invalid_pointer (ptr );
1477
1484
return 0 ;
1478
1485
}
@@ -1647,6 +1654,7 @@ __CPROVER_HIDE:;
1647
1654
__CPROVER_bool __CPROVER_contracts_obeys_contract (
1648
1655
void (* * function_pointer )(void ),
1649
1656
void (* contract )(void ),
1657
+ __CPROVER_bool may_fail ,
1650
1658
__CPROVER_contracts_write_set_ptr_t set )
1651
1659
{
1652
1660
__CPROVER_HIDE :;
@@ -1657,8 +1665,8 @@ __CPROVER_HIDE:;
1657
1665
"__CPROVER_obeys_contract is used only in requires or ensures clauses" );
1658
1666
if ((set -> assume_requires_ctx == 1 ) | (set -> assume_ensures_ctx == 1 ))
1659
1667
{
1660
- // decide if predicate must hold
1661
- if (__VERIFIER_nondet___CPROVER_bool ())
1668
+ // SOUDNESS: allow predicate to fail
1669
+ if (may_fail && __VERIFIER_nondet___CPROVER_bool ())
1662
1670
return 0 ;
1663
1671
1664
1672
// must hold, assign the function pointer to the contract function
0 commit comments