@@ -1165,7 +1165,7 @@ void __CPROVER_contracts_make_invalid_pointer(void **ptr)
11651165
11661166/// \brief Implementation of the `is_fresh` front-end predicate.
11671167///
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
11691169/// which reflect the invocation context: checking vs. replacing a contract,
11701170/// in a requires or an ensures clause context.
11711171/// \param elem First argument of the `is_fresh` predicate
@@ -1232,6 +1232,13 @@ __CPROVER_HIDE:;
12321232 __CPROVER_assume (size <= __CPROVER_max_malloc_size );
12331233 }
12341234
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+
12351242 void * ptr = __CPROVER_allocate (size , 0 );
12361243 * elem = ptr ;
12371244
@@ -1245,7 +1252,6 @@ __CPROVER_HIDE:;
12451252 // __CPROVER_bool record_may_leak = __VERIFIER_nondet___CPROVER_bool();
12461253 // __CPROVER_memory_leak = record_may_leak ? ptr : __CPROVER_memory_leak;
12471254
1248- // record fresh object in the object set
12491255#ifdef __CPROVER_DFCC_DEBUG_LIB
12501256 // manually inlined below
12511257 __CPROVER_contracts_obj_set_add (write_set -> linked_is_fresh , ptr );
@@ -1286,6 +1292,13 @@ __CPROVER_HIDE:;
12861292 __CPROVER_assume (size <= __CPROVER_max_malloc_size );
12871293 }
12881294
1295+ // SOUNDNESS: allow predicate to fail
1296+ if (__VERIFIER_nondet___CPROVER_bool ())
1297+ {
1298+ __CPROVER_contracts_make_invalid_pointer (elem );
1299+ return 0 ;
1300+ }
1301+
12891302 void * ptr = __CPROVER_allocate (size , 0 );
12901303 * elem = ptr ;
12911304
@@ -1300,7 +1313,6 @@ __CPROVER_HIDE:;
13001313 __CPROVER_bool record_may_leak = __VERIFIER_nondet___CPROVER_bool ();
13011314 __CPROVER_memory_leak = record_may_leak ? ptr : __CPROVER_memory_leak ;
13021315
1303- // record fresh object in the caller's write set
13041316#ifdef __CPROVER_DFCC_DEBUG_LIB
13051317 __CPROVER_contracts_obj_set_add (write_set -> linked_allocated , ptr );
13061318#else
@@ -1338,7 +1350,7 @@ __CPROVER_HIDE:;
13381350 if (seen -> elems [object_id ] != 0 )
13391351 return 0 ;
13401352#endif
1341- // record fresh object in the object set
1353+
13421354#ifdef __CPROVER_DFCC_DEBUG_LIB
13431355 // manually inlined below
13441356 __CPROVER_contracts_obj_set_add (seen , ptr );
@@ -1360,6 +1372,23 @@ __CPROVER_HIDE:;
13601372 }
13611373}
13621374
1375+ /// \brief Implementation of the `pointer_in_range_dfcc` front-end predicate.
1376+ ///
1377+ /// The behaviour depends on the boolean flags carried by \p write_set
1378+ /// which reflect the invocation context: checking vs. replacing a contract,
1379+ /// in a requires or an ensures clause context.
1380+ /// \param lb Lower bound pointer
1381+ /// \param ptr Target pointer of the predicate
1382+ /// \param ub Upper bound pointer
1383+ /// \param write_set Write set in which seen/allocated objects are recorded;
1384+ ///
1385+ /// \details The behaviour is as follows:
1386+ /// - When \p set->assume_requires_ctx or \p set->assume_ensures_ctx is `true`,
1387+ /// the predicate checks that \p lb and \p ub are valid, into the same object,
1388+ /// ordered, and checks that \p ptr is between \p lb and \p ub.
1389+ /// - When \p set->assert_requires_ctx or \p set->assert_ensures_ctx is `true`,
1390+ /// the predicate checks that \p lb and \p ub are valid, into the same object,
1391+ /// ordered, and assigns \p ptr to some nondet offset between \p lb and \p ub.
13631392__CPROVER_bool __CPROVER_contracts_pointer_in_range_dfcc (
13641393 void * lb ,
13651394 void * * ptr ,
@@ -1386,7 +1415,11 @@ __CPROVER_HIDE:;
13861415 if (write_set -> assume_requires_ctx | write_set -> assume_ensures_ctx )
13871416 {
13881417 if (__VERIFIER_nondet___CPROVER_bool ())
1418+ {
1419+ // SOUNDNESS: allow predicate to fail
1420+ __CPROVER_contracts_make_invalid_pointer (ptr );
13891421 return 0 ;
1422+ }
13901423
13911424 // add nondet offset
13921425 __CPROVER_size_t offset = __VERIFIER_nondet_size ();
0 commit comments