@@ -537,37 +537,58 @@ void local_SSAt::build_guard(locationt loc)
537
537
(--nodes.end ())->equalities .push_back (equality);
538
538
}
539
539
540
- // / turns assertions into constraints
541
- void local_SSAt::build_assertions (locationt loc)
540
+ // / Recursively go through expr and look for an equality with a pointer
541
+ // / object on the right side and construct a disjunct of possible
542
+ // / concrete assignments.
543
+ bool local_SSAt::get_deallocated_disjunction (const exprt &expr, exprt &result)
542
544
{
543
- if (loc->is_assert ())
545
+ if (expr.id ()==ID_equal && expr.op1 ().id ()==ID_pointer_object &&
546
+ expr.op1 ().op0 ().id ()==ID_symbol)
544
547
{
545
- exprt assert =loc->guard ;
546
- if (assert .id ()==ID_not && assert .op0 ().id ()==ID_equal &&
547
- assert .op0 ().op1 ().id ()==ID_pointer_object &&
548
- assert .op0 ().op1 ().op0 ().id ()==ID_symbol)
548
+ std::string id=id2string (
549
+ to_symbol_expr (expr.op1 ().op0 ()).get_identifier ());
550
+ if (id.find (" __CPROVER_deallocated" )!=std::string::npos)
549
551
{
550
- std::string id= id2string (
551
- to_symbol_expr ( assert . op0 (). op1 (). op0 ()). get_identifier ()) ;
552
- if (id. find ( " __CPROVER_deallocated " )!=std::string::npos )
552
+ const exprt &dealloc_symbol=expr. op1 (). op0 ();
553
+ exprt::operandst d ;
554
+ for ( auto &global : assignments. ssa_objects . globals )
553
555
{
554
- const exprt &dealloc_symbol=assert .op0 ().op1 ().op0 ();
555
- exprt::operandst d;
556
- for (auto &global : assignments.ssa_objects .globals )
556
+ if (global.get_expr ().get_bool (" #concrete" ))
557
557
{
558
- if (global.get_expr ().get_bool (" #concrete" ))
559
- {
560
- d.push_back (
561
- equal_exprt (
562
- dealloc_symbol,
563
- typecast_exprt (
564
- address_of_exprt (global.symbol_expr ()),
565
- dealloc_symbol.type ())));
566
- }
558
+ d.push_back (
559
+ equal_exprt (
560
+ dealloc_symbol,
561
+ typecast_exprt (
562
+ address_of_exprt (global.symbol_expr ()),
563
+ dealloc_symbol.type ())));
567
564
}
568
- assert =implies_exprt (disjunction (d), assert );
569
565
}
566
+ result=disjunction (d);
567
+ return true ;
570
568
}
569
+ }
570
+ else
571
+ {
572
+ // Recursively go through the operands
573
+ if (!expr.has_operands ())
574
+ return false ;
575
+ else
576
+ for (const exprt &op : expr.operands ())
577
+ if (get_deallocated_disjunction (op, result))
578
+ return true ;
579
+ }
580
+ return false ;
581
+ }
582
+
583
+ // / turns assertions into constraints
584
+ void local_SSAt::build_assertions (locationt loc)
585
+ {
586
+ if (loc->is_assert ())
587
+ {
588
+ exprt assert =loc->guard ;
589
+ exprt antecedent;
590
+ if (get_deallocated_disjunction (assert , antecedent))
591
+ assert =implies_exprt (antecedent, assert );
571
592
572
593
const exprt deref_rhs=dereference (assert , loc);
573
594
0 commit comments