@@ -1601,26 +1601,30 @@ class QuantifiedPermModule(val verifier: Verifier)
16011601
16021602 override def conservativeIsPositivePerm (e : sil.Exp ): Boolean = PermissionHelper .conservativeStaticIsStrictlyPositivePerm(e)
16031603
1604+ override def isStrictlyPositivePerm (e : sil.Exp ): Exp = PermissionHelper .isStrictlyPositivePerm(e)
1605+
16041606 object PermissionHelper {
16051607
16061608 def isStrictlyPositivePerm (e : sil.Exp ): Exp = {
16071609 require(e isSubtype sil.Perm , s " found ${e.typ} ( $e), but required Perm " )
1608- val backup = permissionPositiveInternal(translatePerm(e), Some (e))
1610+ // Use backup lazily when needed only. This allows the function to work on WildcardPerms for which
1611+ // translatePerm would throw an exception.
1612+ val backup = () => permissionPositiveInternal(translatePerm(e), Some (e))
16091613 e match {
16101614 case sil.NoPerm () => FalseLit ()
16111615 case sil.FullPerm () => TrueLit ()
16121616 case sil.WildcardPerm () => TrueLit ()
16131617 case sil.EpsilonPerm () => sys.error(" epsilon permissions are not supported by this permission module" )
16141618 case x : sil.LocalVar if isAbstractRead(x) => TrueLit ()
1615- case sil.CurrentPerm (loc) => backup
1619+ case sil.CurrentPerm (loc) => backup()
16161620 case sil.FractionalPerm (left, right) =>
16171621 val (l, r) = (translateExp(left), translateExp(right))
16181622 ((l > IntLit (0 )) && (r > IntLit (0 ))) || ((l < IntLit (0 )) && (r < IntLit (0 )))
16191623 case sil.PermMinus (a) =>
16201624 isStrictlyNegativePerm(a)
16211625 case sil.PermAdd (left, right) =>
1622- (isStrictlyPositivePerm(left) && isStrictlyPositivePerm(right)) || backup
1623- case sil.PermSub (left, right) => backup
1626+ (isStrictlyPositivePerm(left) && isStrictlyPositivePerm(right)) || backup()
1627+ case sil.PermSub (left, right) => backup()
16241628 case sil.PermMul (a, b) =>
16251629 (isStrictlyPositivePerm(a) && isStrictlyPositivePerm(b)) || (isStrictlyNegativePerm(a) && isStrictlyNegativePerm(b))
16261630 case sil.PermDiv (a, b) =>
@@ -1633,7 +1637,7 @@ class QuantifiedPermModule(val verifier: Verifier)
16331637 ((n > IntLit (0 )) && isStrictlyPositivePerm(b)) || ((n < IntLit (0 )) && isStrictlyNegativePerm(b))
16341638 case sil.CondExp (cond, thn, els) =>
16351639 CondExp (translateExp(cond), isStrictlyPositivePerm(thn), isStrictlyPositivePerm(els))
1636- case _ => backup
1640+ case _ => backup()
16371641 }
16381642 }
16391643
@@ -1705,22 +1709,24 @@ class QuantifiedPermModule(val verifier: Verifier)
17051709
17061710 def isStrictlyNegativePerm (e : sil.Exp ): Exp = {
17071711 require(e isSubtype sil.Perm )
1708- val backup = UnExp (Not ,permissionPositiveInternal(translatePerm(e), Some (e), true ))
1712+ // Use backup lazily when needed only. This allows the function to work on WildcardPerms for which
1713+ // translatePerm would throw an exception.
1714+ val backup = () => UnExp (Not ,permissionPositiveInternal(translatePerm(e), Some (e), true ))
17091715 e match {
17101716 case sil.NoPerm () => FalseLit () // strictly negative
17111717 case sil.FullPerm () => FalseLit ()
17121718 case sil.WildcardPerm () => FalseLit ()
17131719 case sil.EpsilonPerm () => sys.error(" epsilon permissions are not supported by this permission module" )
17141720 case x : sil.LocalVar if isAbstractRead(x) => FalseLit ()
1715- case sil.CurrentPerm (loc) => backup
1721+ case sil.CurrentPerm (loc) => backup()
17161722 case sil.FractionalPerm (left, right) =>
17171723 val (l, r) = (translateExp(left), translateExp(right))
17181724 ((l < IntLit (0 )) && (r > IntLit (0 ))) || ((l > IntLit (0 )) && (r < IntLit (0 )))
17191725 case sil.PermMinus (a) =>
17201726 isStrictlyPositivePerm(a)
17211727 case sil.PermAdd (left, right) =>
1722- (isStrictlyNegativePerm(left) && isStrictlyNegativePerm(right)) || backup
1723- case sil.PermSub (left, right) => backup
1728+ (isStrictlyNegativePerm(left) && isStrictlyNegativePerm(right)) || backup()
1729+ case sil.PermSub (left, right) => backup()
17241730 case sil.PermMul (a, b) =>
17251731 (isStrictlyPositivePerm(a) && isStrictlyNegativePerm(b)) || (isStrictlyNegativePerm(a) && isStrictlyPositivePerm(b))
17261732 case sil.PermDiv (a, b) =>
@@ -1733,7 +1739,7 @@ class QuantifiedPermModule(val verifier: Verifier)
17331739 ((n > IntLit (0 )) && isStrictlyNegativePerm(b)) || ((n < IntLit (0 )) && isStrictlyPositivePerm(b))
17341740 case sil.CondExp (cond, thn, els) =>
17351741 CondExp (translateExp(cond), isStrictlyNegativePerm(thn), isStrictlyNegativePerm(els))
1736- case _ => backup
1742+ case _ => backup()
17371743 }
17381744 }
17391745
0 commit comments