Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/main/scala/viper/carbon/modules/PermModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ trait PermModule extends Module with CarbonStateComponent {

def conservativeIsPositivePerm(e: sil.Exp): Boolean

def isStrictlyPositivePerm(e: sil.Exp): Exp
Comment thread
marcoeilers marked this conversation as resolved.

/**
* The current mask.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import viper.silver.verifier.{NullPartialVerificationError, PartialVerificationE

import scala.collection.mutable.ListBuffer
import viper.silver.ast.utility.QuantifiedPermissions.QuantifiedPermissionAssertion
import viper.silver.verifier.reasons.NonPositivePermission

import scala.collection.mutable

Expand Down Expand Up @@ -927,7 +928,8 @@ with DefinednessComponent with ExhaleComponent with InhaleComponent {
, statesStackForPackageStmt: List[Any] = null, insidePackageStmt: Boolean = false): (Stmt,Stmt) = {
duringFold = true
foldInfo = acc
val stmt = exhaleSingleWithoutDefinedness(Permissions.multiplyExpByPerm(acc.loc.predicateBody(verifier.program, env.allDefinedNames(program)).get,acc.perm), error, havocHeap = false,
val stmt = Assert(permModule.isStrictlyPositivePerm(acc.perm), error.dueTo(NonPositivePermission(acc.perm))) ++
exhaleSingleWithoutDefinedness(Permissions.multiplyExpByPerm(acc.loc.predicateBody(verifier.program, env.allDefinedNames(program)).get,acc.perm), error, havocHeap = false,
statesStackForPackageStmt = statesStackForPackageStmt, insidePackageStmt = insidePackageStmt) ++
inhale(Seq((acc, error)), addDefinednessChecks = false, statesStackForPackageStmt, insidePackageStmt)
val stmtLast = Assume(predicateTrigger(heapModule.currentStateExps, acc.loc)) ++ {
Expand Down Expand Up @@ -972,6 +974,7 @@ with DefinednessComponent with ExhaleComponent with InhaleComponent {
val translatedArgs = location.args map translateExp
Assume(translateLocationAccess(location) === getPredicateFrame(predicate,translatedArgs)._1)
} ++
Assert(permModule.isStrictlyPositivePerm(acc.perm), error.dueTo(NonPositivePermission(acc.perm))) ++
Comment thread
marcoeilers marked this conversation as resolved.
Outdated
(if(exhaleUnfoldedPredicate)
exhaleSingleWithoutDefinedness(acc, error, havocHeap = false, statesStackForPackageStmt = statesStackForPackageStmt, insidePackageStmt = insidePackageStmt)
else Nil) ++ inhale(Seq((Permissions.multiplyExpByPerm(acc.loc.predicateBody(verifier.program, env.allDefinedNames(program)).get,acc.perm), error)), addDefinednessChecks = false, statesStackForPackageStmt = statesStackForPackageStmt, insidePackageStmt = insidePackageStmt)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1601,26 +1601,30 @@ class QuantifiedPermModule(val verifier: Verifier)

override def conservativeIsPositivePerm(e: sil.Exp): Boolean = PermissionHelper.conservativeStaticIsStrictlyPositivePerm(e)

override def isStrictlyPositivePerm(e: sil.Exp): Exp = PermissionHelper.isStrictlyPositivePerm(e)

object PermissionHelper {

def isStrictlyPositivePerm(e: sil.Exp): Exp = {
require(e isSubtype sil.Perm, s"found ${e.typ} ($e), but required Perm")
val backup = permissionPositiveInternal(translatePerm(e), Some(e))
// Use backup lazily when needed only. This allows the function to work on WildcardPerms for which
// translatePerm would throw an exception.
val backup = () => permissionPositiveInternal(translatePerm(e), Some(e))
e match {
case sil.NoPerm() => FalseLit()
case sil.FullPerm() => TrueLit()
case sil.WildcardPerm() => TrueLit()
case sil.EpsilonPerm() => sys.error("epsilon permissions are not supported by this permission module")
case x: sil.LocalVar if isAbstractRead(x) => TrueLit()
case sil.CurrentPerm(loc) => backup
case sil.CurrentPerm(loc) => backup()
case sil.FractionalPerm(left, right) =>
val (l, r) = (translateExp(left), translateExp(right))
((l > IntLit(0)) && (r > IntLit(0))) || ((l < IntLit(0)) && (r < IntLit(0)))
case sil.PermMinus(a) =>
isStrictlyNegativePerm(a)
case sil.PermAdd(left, right) =>
(isStrictlyPositivePerm(left) && isStrictlyPositivePerm(right)) || backup
case sil.PermSub(left, right) => backup
(isStrictlyPositivePerm(left) && isStrictlyPositivePerm(right)) || backup()
case sil.PermSub(left, right) => backup()
case sil.PermMul(a, b) =>
(isStrictlyPositivePerm(a) && isStrictlyPositivePerm(b)) || (isStrictlyNegativePerm(a) && isStrictlyNegativePerm(b))
case sil.PermDiv(a, b) =>
Expand All @@ -1633,7 +1637,7 @@ class QuantifiedPermModule(val verifier: Verifier)
((n > IntLit(0)) && isStrictlyPositivePerm(b)) || ((n < IntLit(0)) && isStrictlyNegativePerm(b))
case sil.CondExp(cond, thn, els) =>
CondExp(translateExp(cond), isStrictlyPositivePerm(thn), isStrictlyPositivePerm(els))
case _ => backup
case _ => backup()
}
}

Expand Down Expand Up @@ -1705,22 +1709,24 @@ class QuantifiedPermModule(val verifier: Verifier)

def isStrictlyNegativePerm(e: sil.Exp): Exp = {
require(e isSubtype sil.Perm)
val backup = UnExp(Not,permissionPositiveInternal(translatePerm(e), Some(e), true))
// Use backup lazily when needed only. This allows the function to work on WildcardPerms for which
// translatePerm would throw an exception.
val backup = () => UnExp(Not,permissionPositiveInternal(translatePerm(e), Some(e), true))
e match {
case sil.NoPerm() => FalseLit() // strictly negative
case sil.FullPerm() => FalseLit()
case sil.WildcardPerm() => FalseLit()
case sil.EpsilonPerm() => sys.error("epsilon permissions are not supported by this permission module")
case x: sil.LocalVar if isAbstractRead(x) => FalseLit()
case sil.CurrentPerm(loc) => backup
case sil.CurrentPerm(loc) => backup()
case sil.FractionalPerm(left, right) =>
val (l, r) = (translateExp(left), translateExp(right))
((l < IntLit(0)) && (r > IntLit(0))) || ((l > IntLit(0)) && (r < IntLit(0)))
case sil.PermMinus(a) =>
isStrictlyPositivePerm(a)
case sil.PermAdd(left, right) =>
(isStrictlyNegativePerm(left) && isStrictlyNegativePerm(right)) || backup
case sil.PermSub(left, right) => backup
(isStrictlyNegativePerm(left) && isStrictlyNegativePerm(right)) || backup()
case sil.PermSub(left, right) => backup()
case sil.PermMul(a, b) =>
(isStrictlyPositivePerm(a) && isStrictlyNegativePerm(b)) || (isStrictlyNegativePerm(a) && isStrictlyPositivePerm(b))
case sil.PermDiv(a, b) =>
Expand All @@ -1733,7 +1739,7 @@ class QuantifiedPermModule(val verifier: Verifier)
((n > IntLit(0)) && isStrictlyNegativePerm(b)) || ((n < IntLit(0)) && isStrictlyPositivePerm(b))
case sil.CondExp(cond, thn, els) =>
CondExp(translateExp(cond), isStrictlyNegativePerm(thn), isStrictlyNegativePerm(els))
case _ => backup
case _ => backup()
}
}

Expand Down