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

Adds functions as a dependency to methods #549

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
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
9 changes: 5 additions & 4 deletions src/main/scala/viper/silver/utility/Caching.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ trait DependencyAware {
val func = p.findFunction(func_app.funcname)
if (!marker.contains(func)) {
markSubAST(func, marker)
Seq(func) ++ getDependenciesRec(p, func.pres ++ func.posts ++ extractOptionalNode(func.body), marker)
// `func` do not need to be returned because all functions are always considered as a dependency
getDependenciesRec(p, func.pres ++ func.posts ++ extractOptionalNode(func.body), marker)
} else Nil
case pred_access: PredicateAccess =>
val pred = p.findPredicate(pred_access.predicateName)
Expand All @@ -57,6 +58,7 @@ trait DependencyAware {
*
* This method is imprecise, but practical. Here's a list of known imprecisions:
* - axioms are considered as global dependencies (even if they don't influence the method);
* - functions are considered as global dependencies (even if they don't influence the method);
* - fields are considered as global dependencies (even if they don't influence the method);
* - concrete predicates used abstractly (w/o unfolding) bring transitive dependencies via their body.
*
Expand All @@ -73,7 +75,7 @@ trait DependencyAware {
def getDependencies(p: Program, m: Method): List[Hashable] = {
val marker: mutable.Set[Hashable] = mutable.Set.empty
markSubAST(m, marker)
Seq(m) ++ p.domains ++ p.fields ++
Seq(m) ++ p.domains ++ p.functions ++ p.fields ++
(m.pres ++ m.posts ++ m.body.toSeq).flatMap {
n => n.deepCollect {
case method_call: MethodCall =>
Expand All @@ -83,8 +85,7 @@ trait DependencyAware {
method.pres ++ method.posts ++
getDependenciesRec(p, method.formalArgs ++ method.formalReturns ++ method.pres ++ method.posts, marker)
} else Nil
case func_app: FuncApp =>
getDependenciesRec(p, Seq(func_app), marker)
// function calls do not need to be considered because all functions are always considered as a dependency
case pred_access: PredicateAccess =>
getDependenciesRec(p, Seq(pred_access), marker)
} flatten
Expand Down
12 changes: 6 additions & 6 deletions src/test/scala/MethodDependencyTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,13 @@ class MethodDependencyTests extends AnyFunSuite with Matchers {

// println(p)

val global_deps: List[Hashable] = List(D0, f0,f1,f2,f3,f4)
val via_pre_deps: List[Hashable] = List(fun0, p0)
val via_post_deps: List[Hashable] = List(fun1, p1)
val via_body_deps: List[Hashable] = List(fun2, p2) ++ m0.formalArgs ++ m0.formalReturns ++ m0.pres ++ m0.posts
val transitive_deps: List[Hashable] = List(fun4, p4)
val global_deps: List[Hashable] = List(D0, f0,f1,f2,f3,f4, fun0,fun1,fun2,fun3,fun4)
val via_pre_deps: List[Hashable] = List(p0)
val via_post_deps: List[Hashable] = List(p1)
val via_body_deps: List[Hashable] = List(p2) ++ m0.formalArgs ++ m0.formalReturns ++ m0.pres ++ m0.posts
val transitive_deps: List[Hashable] = List(p4)
val must_be_deps: List[Hashable] = List(test) ++ global_deps ++ via_pre_deps ++ via_post_deps ++ via_body_deps ++ transitive_deps
val must_not_be_deps: List[Hashable] = List(fun3, p3, m0.body.get, m1)
val must_not_be_deps: List[Hashable] = List(p3, m0.body.get, m1)

val computed_deps: List[Hashable] = p.getDependencies(p, test)

Expand Down