@@ -1165,7 +1165,7 @@ void __CPROVER_contracts_make_invalid_pointer(void **ptr)
1165
1165
1166
1166
/// \brief Implementation of the `is_fresh` front-end predicate.
1167
1167
///
1168
- /// The behaviour depends on the boolean flags carried by \p set
1168
+ /// The behaviour depends on the boolean flags carried by \p write_set
1169
1169
/// which reflect the invocation context: checking vs. replacing a contract,
1170
1170
/// in a requires or an ensures clause context.
1171
1171
/// \param elem First argument of the `is_fresh` predicate
@@ -1232,6 +1232,13 @@ __CPROVER_HIDE:;
1232
1232
__CPROVER_assume (size <= __CPROVER_max_malloc_size );
1233
1233
}
1234
1234
1235
+ // SOUNDNESS: allow predicate to fail
1236
+ if (__VERIFIER_nondet___CPROVER_bool ())
1237
+ {
1238
+ __CPROVER_contracts_make_invalid_pointer (elem );
1239
+ return 0 ;
1240
+ }
1241
+
1235
1242
void * ptr = __CPROVER_allocate (size , 0 );
1236
1243
* elem = ptr ;
1237
1244
@@ -1286,6 +1293,13 @@ __CPROVER_HIDE:;
1286
1293
__CPROVER_assume (size <= __CPROVER_max_malloc_size );
1287
1294
}
1288
1295
1296
+ // SOUNDNESS: allow predicate to fail
1297
+ if (__VERIFIER_nondet___CPROVER_bool ())
1298
+ {
1299
+ __CPROVER_contracts_make_invalid_pointer (elem );
1300
+ return 0 ;
1301
+ }
1302
+
1289
1303
void * ptr = __CPROVER_allocate (size , 0 );
1290
1304
* elem = ptr ;
1291
1305
@@ -1338,7 +1352,7 @@ __CPROVER_HIDE:;
1338
1352
if (seen -> elems [object_id ] != 0 )
1339
1353
return 0 ;
1340
1354
#endif
1341
- // record fresh object in the object set
1355
+ // record fresh object in the object set
1342
1356
#ifdef __CPROVER_DFCC_DEBUG_LIB
1343
1357
// manually inlined below
1344
1358
__CPROVER_contracts_obj_set_add (seen , ptr );
@@ -1360,6 +1374,23 @@ __CPROVER_HIDE:;
1360
1374
}
1361
1375
}
1362
1376
1377
+ /// \brief Implementation of the `pointer_in_range_dfcc` front-end predicate.
1378
+ ///
1379
+ /// The behaviour depends on the boolean flags carried by \p write_set
1380
+ /// which reflect the invocation context: checking vs. replacing a contract,
1381
+ /// in a requires or an ensures clause context.
1382
+ /// \param lb Lower bound pointer
1383
+ /// \param ptr Target pointer of the predicate
1384
+ /// \param ub Upper bound pointer
1385
+ /// \param write_set Write set in which seen/allocated objects are recorded;
1386
+ ///
1387
+ /// \details The behaviour is as follows:
1388
+ /// - When \p set->assume_requires_ctx or \p set->assume_ensures_ctx is `true`,
1389
+ /// the predicate checks that \p lb and \p ub are valid, into the same object,
1390
+ /// ordered, and checks that \p ptr is between \p lb and \p ub.
1391
+ /// - When \p set->assert_requires_ctx or \p set->assert_ensures_ctx is `true`,
1392
+ /// the predicate checks that \p lb and \p ub are valid, into the same object,
1393
+ /// ordered, and assigns \p ptr to some nondet offset between \p lb and \p ub.
1363
1394
__CPROVER_bool __CPROVER_contracts_pointer_in_range_dfcc (
1364
1395
void * lb ,
1365
1396
void * * ptr ,
@@ -1386,7 +1417,11 @@ __CPROVER_HIDE:;
1386
1417
if (write_set -> assume_requires_ctx | write_set -> assume_ensures_ctx )
1387
1418
{
1388
1419
if (__VERIFIER_nondet___CPROVER_bool ())
1420
+ {
1421
+ // SOUNDNESS: allow predicate to fail
1422
+ __CPROVER_contracts_make_invalid_pointer (ptr );
1389
1423
return 0 ;
1424
+ }
1390
1425
1391
1426
// add nondet offset
1392
1427
__CPROVER_size_t offset = __VERIFIER_nondet_size ();
0 commit comments