@@ -160,7 +160,8 @@ def liftProcedureCallAbstraction(ctx: util.IRContext): util.IRContext = {
160
160
161
161
while (removeDeadInParams(ctx.program)) {}
162
162
163
- ctx.copy(specification = specToProcForm(ctx.specification, formalParams.mappingInparam, formalParams.mappingOutparam))
163
+ ctx.program.procedures.foreach(SpecFixer .updateInlineSpec(formalParams.mappingInparam, formalParams.mappingOutparam))
164
+ ctx.copy(specification = SpecFixer .specToProcForm(ctx.specification, formalParams.mappingInparam, formalParams.mappingOutparam))
164
165
}
165
166
166
167
def clearParams (p : Program ) = {
@@ -395,22 +396,25 @@ def inOutParams(
395
396
396
397
val alwaysReturnParams = (0 to 7 ).map(i => Register (s " R $i" , 64 ))
397
398
399
+
400
+ val pc = Register (" _PC" , 64 )
401
+
398
402
val inout = readWrites.collect {
399
403
case (proc, rws) if p.mainProcedure == proc => {
400
404
// no callers of main procedure so keep the whole read/write set
401
405
// of registers
402
406
403
407
val outParams = (overapprox.intersect(DefinedOnAllPaths .proc(proc)))
404
408
val inParams = lives(proc)._1
405
- proc -> (inParams, outParams)
409
+ proc -> (inParams + pc , outParams + pc )
406
410
}
407
411
case (proc, rws) => {
408
412
val liveStart = lives(proc)._1
409
413
val liveEnd = lives(proc)._2 ++ alwaysReturnParams
410
414
411
415
val outParams = liveEnd.intersect(rws.writes)
412
416
val inParams = liveStart
413
- proc -> (inParams, outParams)
417
+ proc -> (inParams + pc , outParams + pc )
414
418
}
415
419
}.toMap
416
420
@@ -540,18 +544,49 @@ class SetActualParams(
540
544
541
545
}
542
546
543
- def specToProcForm (
544
- spec : Specification ,
545
- mappingInparam : Map [Procedure , Map [LocalVar , Variable ]],
546
- mappingOutparam : Map [Procedure , Map [LocalVar , Variable ]]
547
- ): Specification = {
547
+
548
+ object SpecFixer {
548
549
import boogie .*
549
550
550
- def toNameMapping (v : Map [LocalVar , Variable ]): Map [String , String ] = {
551
- v.map(v => (v._2.name, v._1.name)) ++ v.map(v => (" Gamma_" + v._2.name, " Gamma_" + v._1.name))
551
+ class ExprToOld (varInPre : Map [String , Variable ], varInPost : Map [String , Variable ],
552
+ initIsPost : Boolean = false ) extends CILVisitor {
553
+
554
+ var isPost = initIsPost
555
+
556
+ override def vexpr (e : Expr ) = e match {
557
+ case OldExpr (inner) if ! isPost => {
558
+ throw Exception (" nested Old or Old in single-state context" )
559
+ }
560
+ case OldExpr (inner) if isPost => {
561
+ isPost = false
562
+ ChangeDoChildrenPost (inner, e => {
563
+ isPost = true
564
+ e
565
+ })
566
+ }
567
+ case _ => DoChildren ()
568
+ }
569
+
570
+ def changeVar (v : Variable ) = {
571
+ val repl = v match {
572
+ case l : Variable if isPost && varInPost.contains(l.name) => varInPost(l.name)
573
+ case l : Variable if varInPre.contains(l.name) => varInPre(l.name)
574
+ case o => o
575
+ }
576
+ ChangeTo (repl)
577
+ }
578
+
579
+ override def vlvar (v : Variable ) = changeVar(v)
580
+ override def vrvar (v : Variable ) = changeVar(v)
581
+
582
+ }
583
+
584
+ def convVarToOldExpr (varInPre : Map [String , Variable ], varInPost : Map [String , Variable ], isPost : Boolean = false )(
585
+ b : Expr
586
+ ) : Expr = {
587
+ val visitor = ExprToOld (varInPre, varInPost, isPost)
588
+ visit_expr(visitor, b)
552
589
}
553
- val varToInVar : Map [String , Map [String , String ]] = mappingInparam.map(p => (p._1.procName -> toNameMapping(p._2)))
554
- val varToOutVar : Map [String , Map [String , String ]] = mappingOutparam.map(p => (p._1.procName -> toNameMapping(p._2)))
555
590
556
591
def convVarToOld (varInPre : Map [String , String ], varInPost : Map [String , String ], isPost : Boolean = false )(
557
592
b : BExpr
@@ -560,7 +595,10 @@ def specToProcForm(
560
595
b match {
561
596
case b : BVariable if isPost && varInPost.contains(b.name) => BVariable (varInPost(b.name), b.getType, b.scope)
562
597
case b : BVariable if ! isPost && varInPre.contains(b.name) => BVariable (varInPre(b.name), b.getType, b.scope)
563
- case b : BVar => b
598
+ case b : BVariable if ! isPost =>
599
+ println(" sad" )
600
+ println(b)
601
+ b
564
602
// case b : _ => varToOld(b)
565
603
case b : BLiteral => b
566
604
case b : BVExtract => b.copy(body = varToOld(b.body))
@@ -590,20 +628,61 @@ def specToProcForm(
590
628
case b : GammaStore => b.copy(index = varToOld(b.index), value = varToOld(b.value))
591
629
case b : L => b.copy(index = varToOld(b.index))
592
630
case b : SpecVar => b
631
+ case b : BVar =>
632
+ println(b)
633
+ ???
593
634
}
594
635
}
595
636
596
- val ns = spec.copy(subroutines = spec.subroutines.map(s => {
597
- if (s.requires.nonEmpty || s.ensures.nonEmpty) {
598
- val in = varToInVar(s.name)
599
- val out = varToOutVar(s.name)
600
- s.copy(
601
- requires = s.requires.map(convVarToOld(in, out, false )),
602
- ensures = s.ensures.map(convVarToOld(in, out, true ))
603
- )
604
- } else {
605
- s
637
+ def updateInlineSpec (
638
+ mappingInparam : Map [Procedure , Map [LocalVar , Variable ]],
639
+ mappingOutparam : Map [Procedure , Map [LocalVar , Variable ]])(p : Procedure ) = {
640
+
641
+
642
+ def toNameMapping (v : Map [LocalVar , Variable ]): Map [String , String ] = {
643
+ v.map(v => (v._2.name, v._1.name)) ++ v.map(v => (" Gamma_" + v._2.name, " Gamma_" + v._1.name))
606
644
}
607
- }))
608
- ns
645
+
646
+ val varToInVar = mappingInparam.map(p => (p._1 -> toNameMapping(p._2)))
647
+ val varToOutVar = mappingOutparam.map(p => (p._1 -> toNameMapping(p._2)))
648
+
649
+ p.requires = p.requires.map(convVarToOld(varToInVar(p), varToOutVar(p), false ))
650
+ p.ensures = p.ensures.map(convVarToOld(varToInVar(p), varToOutVar(p), true ))
651
+
652
+ def toVarMapping (v : Map [LocalVar , Variable ]): Map [String , Variable ] = {
653
+ v.map(v => (v._2.name, v._1))
654
+ }
655
+
656
+ p.requiresExpr = p.requiresExpr.map(convVarToOldExpr(toVarMapping(mappingInparam(p)), toVarMapping(mappingOutparam(p)), false ))
657
+ p.ensuresExpr = p.ensuresExpr.map(convVarToOldExpr(toVarMapping(mappingInparam(p)), toVarMapping(mappingOutparam(p)), true ))
658
+
659
+ }
660
+
661
+ def specToProcForm (
662
+ spec : Specification ,
663
+ mappingInparam : Map [Procedure , Map [LocalVar , Variable ]],
664
+ mappingOutparam : Map [Procedure , Map [LocalVar , Variable ]]
665
+ ): Specification = {
666
+
667
+ def toNameMapping (v : Map [LocalVar , Variable ]): Map [String , String ] = {
668
+ v.map(v => (v._2.name, v._1.name)) ++ v.map(v => (" Gamma_" + v._2.name, " Gamma_" + v._1.name))
669
+ }
670
+ val varToInVar : Map [String , Map [String , String ]] = mappingInparam.map(p => (p._1.procName -> toNameMapping(p._2)))
671
+ val varToOutVar : Map [String , Map [String , String ]] = mappingOutparam.map(p => (p._1.procName -> toNameMapping(p._2)))
672
+
673
+ val ns = spec.copy(subroutines = spec.subroutines.map(s => {
674
+ if (s.requires.nonEmpty || s.ensures.nonEmpty) {
675
+ val in = varToInVar(s.name)
676
+ val out = varToOutVar(s.name)
677
+ s.copy(
678
+ requires = s.requires.map(convVarToOld(in, out, false )),
679
+ ensures = s.ensures.map(convVarToOld(in, out, true ))
680
+ )
681
+ } else {
682
+ s
683
+ }
684
+ }))
685
+ ns
686
+ }
609
687
}
688
+
0 commit comments