Skip to content

Commit fe66937

Browse files
committed
Java: Make more finegrained dataflow dispatch viable callable heuristic.
1 parent 3a864d3 commit fe66937

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

java/ql/lib/semmle/code/java/Element.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ class Element extends @element, Top {
3636
*/
3737
predicate fromSource() { this.getCompilationUnit().isSourceFile() }
3838

39+
/**
40+
* Holds if this element is from source and classified as a stub implementation.
41+
* An implementation is considered a stub, if the the path to the
42+
* source file contains `/stubs/`.
43+
*/
44+
predicate isStub() { this.fromSource() and this.getFile().getAbsolutePath().matches("%/stubs/%") }
45+
3946
/** Gets the compilation unit that this element belongs to. */
4047
CompilationUnit getCompilationUnit() { result = this.getFile() }
4148

java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,29 @@ private module DispatchImpl {
4040
else any()
4141
}
4242

43-
/** Gets a viable implementation of the target of the given `Call`. */
43+
/**
44+
* Gets a viable implementation of the target of the given `Call`.
45+
* The following heuristic is applied for finding the appropriate callable:
46+
* 1. If an exact manual model exists, only dispatch to the summarized callable.
47+
* 2. If a (non exact) manual model exists and/or if the source code is available, dispatch to both/either.
48+
* 3. Only dispatch to a summarized callable (based on a generated model) if neither of the above apply.
49+
*/
4450
DataFlowCallable viableCallable(DataFlowCall c) {
45-
result.asCallable() = sourceDispatch(c.asCall())
46-
or
47-
result.asSummarizedCallable().getACall() = c.asCall()
51+
exists(Call call | call = c.asCall() |
52+
result.asCallable() = sourceDispatch(call)
53+
or
54+
not (
55+
// Only use summarized callables with generated summaries in case
56+
// we are not able to dispatch to a source declaration.
57+
// Note that if applyGeneratedModel holds it implies that there doesn't
58+
// exist a manual (exact) model.
59+
exists(Callable callable | callable = sourceDispatch(call) |
60+
callable.fromSource() and not callable.isStub()
61+
) and
62+
result.asSummarizedCallable().applyGeneratedModel()
63+
) and
64+
result.asSummarizedCallable().getACall() = call
65+
)
4866
}
4967

5068
/**

0 commit comments

Comments
 (0)