@@ -29,10 +29,11 @@ trait ChunkSupportRules extends SymbolicExecutionRules {
2929 argsExp : Option [Seq [ast.Exp ]],
3030 perms : Term ,
3131 permsExp : Option [ast.Exp ],
32+ returnSnap : Boolean ,
3233 ve : VerificationError ,
3334 v : Verifier ,
3435 description : String )
35- (Q : (State , Heap , Term , Verifier ) => VerificationResult )
36+ (Q : (State , Heap , Option [ Term ] , Verifier ) => VerificationResult )
3637 : VerificationResult
3738
3839 def produce (s : State , h : Heap , ch : NonQuantifiedChunk , v : Verifier )
@@ -71,17 +72,18 @@ object chunkSupporter extends ChunkSupportRules {
7172 argsExp : Option [Seq [ast.Exp ]],
7273 perms : Term ,
7374 permsExp : Option [ast.Exp ],
75+ returnSnap : Boolean ,
7476 ve : VerificationError ,
7577 v : Verifier ,
7678 description : String )
77- (Q : (State , Heap , Term , Verifier ) => VerificationResult )
79+ (Q : (State , Heap , Option [ Term ] , Verifier ) => VerificationResult )
7880 : VerificationResult = {
7981
80- consume2(s, h, resource, args, argsExp, perms, permsExp, ve, v)((s2, h2, optSnap, v2) =>
82+ consume2(s, h, resource, args, argsExp, perms, permsExp, returnSnap, ve, v)((s2, h2, optSnap, v2) =>
8183 optSnap match {
8284 case Some (snap) =>
83- Q (s2, h2, snap.convert(sorts.Snap ), v2)
84- case None =>
85+ Q (s2, h2, Some ( snap.convert(sorts.Snap ) ), v2)
86+ case None if returnSnap =>
8587 /* Not having consumed anything could mean that we are in an infeasible
8688 * branch, or that the permission amount to consume was zero.
8789 *
@@ -91,7 +93,8 @@ object chunkSupporter extends ChunkSupportRules {
9193 */
9294 val fresh = v2.decider.fresh(sorts.Snap , Option .when(withExp)(PUnknown ()))
9395 val s3 = s2.copy(functionRecorder = s2.functionRecorder.recordFreshSnapshot(fresh.applicable))
94- Q (s3, h2, fresh, v2)
96+ Q (s3, h2, Some (fresh), v2)
97+ case None => Q (s2, h2, None , v2)
9598 })
9699 }
97100
@@ -102,6 +105,7 @@ object chunkSupporter extends ChunkSupportRules {
102105 argsExp : Option [Seq [ast.Exp ]],
103106 perms : Term ,
104107 permsExp : Option [ast.Exp ],
108+ returnSnap : Boolean ,
105109 ve : VerificationError ,
106110 v : Verifier )
107111 (Q : (State , Heap , Option [Term ], Verifier ) => VerificationResult )
@@ -111,24 +115,28 @@ object chunkSupporter extends ChunkSupportRules {
111115 if (s.exhaleExt) {
112116 val failure = createFailure(ve, v, s, " chunk consume in package" )
113117 magicWandSupporter.transfer(s, perms, permsExp, failure, Seq (), v)(consumeGreedy(_, _, id, args, _, _, _))((s1, optCh, v1) =>
114- Q (s1, h, optCh.flatMap(ch => Some (ch.snap)), v1))
118+ if (returnSnap){
119+ Q (s1, h, optCh.flatMap(ch => Some (ch.snap)), v1)
120+ } else {
121+ Q (s1, h, None , v1)
122+ })
115123 } else {
116124 executionFlowController.tryOrFail2[Heap , Option [Term ]](s.copy(h = h), v)((s1, v1, QS ) =>
117125 if (s1.moreCompleteExhale) {
118- moreCompleteExhaleSupporter.consumeComplete(s1, s1.h, resource, args, argsExp, perms, permsExp, ve, v1)((s2, h2, snap2, v2) => {
126+ moreCompleteExhaleSupporter.consumeComplete(s1, s1.h, resource, args, argsExp, perms, permsExp, returnSnap, ve, v1)((s2, h2, snap2, v2) => {
119127 QS (s2.copy(h = s.h), h2, snap2, v2)
120128 })
121129 } else {
122130 consumeGreedy(s1, s1.h, id, args, perms, permsExp, v1) match {
123131 case (Complete (), s2, h2, optCh2) =>
124132 val snap = optCh2 match {
125- case None => None
126- case Some (ch) =>
133+ case Some (ch) if returnSnap =>
127134 if (v1.decider.check(IsPositive (perms), Verifier .config.checkTimeout())) {
128135 Some (ch.snap)
129136 } else {
130137 Some (Ite (IsPositive (perms), ch.snap.convert(sorts.Snap ), Unit ))
131138 }
139+ case _ => None
132140 }
133141 QS (s2.copy(h = s.h), h2, snap, v1)
134142 case _ if v1.decider.checkSmoke(true ) =>
0 commit comments