Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not perform new checks and imports if the termination plugin is deactivated... #728

Merged
merged 1 commit into from
Aug 4, 2023
Merged
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ class TerminationPlugin(@unused reporter: viper.silver.reporter.Reporter,
}

override def beforeTranslate(input: PProgram): PProgram = {
if (deactivated)
return input

val allClauseTypes: Set[Any] = decreasesClauses.flatMap{
case PDecreasesTuple(Seq(), _) => Seq(())
case PDecreasesTuple(exps, _) => exps.map(e => e.typ match {
Expand Down Expand Up @@ -240,27 +243,29 @@ class TerminationPlugin(@unused reporter: viper.silver.reporter.Reporter,
override def beforeVerify(input: Program): Program = {
// Prevent potentially unsafe (mutually) recursive function calls in function postcondtions
// for all functions that don't have a decreases clause
lazy val cycles = Functions.findFunctionCyclesViaOptimized(input, func => func.body.toSeq)
for (f <- input.functions) {
val hasDecreasesClause = (f.pres ++ f.posts).exists(p => p.shallowCollect {
case dc: DecreasesClause => dc
}.nonEmpty)
if (!hasDecreasesClause) {
val funcCycles = cycles.get(f)
val problematicFuncApps = f.posts.flatMap(p => p.shallowCollect {
case fa: FuncApp if fa.func(input) == f => fa
case fa: FuncApp if funcCycles.isDefined && funcCycles.get.contains(fa.func(input)) => fa
}).toSet
for (fa <- problematicFuncApps) {
val calledFunc = fa.func(input)
if (calledFunc == f) {
if (fa.args == f.formalArgs.map(_.localVar)) {
reportError(ConsistencyError(s"Function ${f.name} has a self-reference in its postcondition and must be proven to be well-founded. Use \"result\" instead to refer to the result of the function.", fa.pos))
if (!deactivated) {
lazy val cycles = Functions.findFunctionCyclesViaOptimized(input, func => func.body.toSeq)
for (f <- input.functions) {
val hasDecreasesClause = (f.pres ++ f.posts).exists(p => p.shallowCollect {
case dc: DecreasesClause => dc
}.nonEmpty)
if (!hasDecreasesClause) {
val funcCycles = cycles.get(f)
val problematicFuncApps = f.posts.flatMap(p => p.shallowCollect {
case fa: FuncApp if fa.func(input) == f => fa
case fa: FuncApp if funcCycles.isDefined && funcCycles.get.contains(fa.func(input)) => fa
}).toSet
for (fa <- problematicFuncApps) {
val calledFunc = fa.func(input)
if (calledFunc == f) {
if (fa.args == f.formalArgs.map(_.localVar)) {
reportError(ConsistencyError(s"Function ${f.name} has a self-reference in its postcondition and must be proven to be well-founded. Use \"result\" instead to refer to the result of the function.", fa.pos))
} else {
reportError(ConsistencyError(s"Function ${f.name} has a self-reference in its postcondition and must be proven to be well-founded. Add a \"decreases\" clause to prove well-foundedness.", fa.pos))
}
} else {
reportError(ConsistencyError(s"Function ${f.name} has a self-reference in its postcondition and must be proven to be well-founded. Add a \"decreases\" clause to prove well-foundedness.", fa.pos))
reportError(ConsistencyError(s"Function ${f.name} has a call to mutually-recursive function ${calledFunc.name} in its postcondition and must be proven to be well-founded. Add a \"decreases\" clause to prove well-foundedness.", fa.pos))
}
} else {
reportError(ConsistencyError(s"Function ${f.name} has a call to mutually-recursive function ${calledFunc.name} in its postcondition and must be proven to be well-founded. Add a \"decreases\" clause to prove well-foundedness.", fa.pos))
}
}
}
Expand Down
Loading