Skip to content

Commit f196538

Browse files
authored
Merge pull request #714 from owen-mc/fix-get-enclosing-callable
Extend DataFlowCallable to include file scopes
2 parents 76a0a51 + b9ff1cc commit f196538

File tree

4 files changed

+53
-9
lines changed

4 files changed

+53
-9
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Fixed a bug where dataflow steps were ignored if both ends were inside the initialiser routine of a file-level variable.

ql/lib/semmle/go/dataflow/internal/DataFlowDispatch.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ DataFlowCallable viableCallable(CallExpr ma) {
9393
else
9494
if isInterfaceMethodCall(call)
9595
then result = getRestrictedInterfaceTarget(call)
96-
else result = call.getACalleeIncludingExternals()
96+
else result.asCallable() = call.getACalleeIncludingExternals()
9797
)
9898
}
9999

ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,15 @@ private newtype TNode =
2626
/** Nodes intended for only use inside the data-flow libraries. */
2727
module Private {
2828
/** Gets the callable in which this node occurs. */
29-
DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCallable() }
29+
DataFlowCallable nodeGetEnclosingCallable(Node n) {
30+
result.asCallable() = n.getEnclosingCallable()
31+
or
32+
not exists(n.getEnclosingCallable()) and result.asFileScope() = n.getFile()
33+
}
3034

3135
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
3236
predicate isParameterNode(ParameterNode p, DataFlowCallable c, int pos) {
33-
p.isParameterOf(c, pos)
37+
p.isParameterOf(c.asCallable(), pos)
3438
}
3539

3640
/** A data flow node that represents returning a value from a function. */
@@ -108,9 +112,11 @@ module Public {
108112
Callable getEnclosingCallable() {
109113
result.getFuncDef() = this.getRoot()
110114
or
111-
this = MkSummarizedParameterNode(result, _)
112-
or
113-
this = MkSummaryInternalNode(result, _)
115+
exists(DataFlowCallable dfc | result = dfc.asCallable() |
116+
this = MkSummarizedParameterNode(dfc, _)
117+
or
118+
this = MkSummaryInternalNode(dfc, _)
119+
)
114120
}
115121

116122
/** Gets the type of this node. */
@@ -570,7 +576,9 @@ module Public {
570576
Callable c;
571577
int i;
572578

573-
SummarizedParameterNode() { this = MkSummarizedParameterNode(c, i) }
579+
SummarizedParameterNode() {
580+
this = MkSummarizedParameterNode(any(DataFlowCallable dfc | c = dfc.asCallable()), i)
581+
}
574582

575583
// There are no AST representations of summarized parameter nodes
576584
override ControlFlow::Root getRoot() { none() }

ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,35 @@ class DataFlowType = Type;
197197

198198
class DataFlowLocation = Location;
199199

200-
class DataFlowCallable = Callable;
200+
private newtype TDataFlowCallable =
201+
TCallable(Callable c) or
202+
TFileScope(File f)
203+
204+
class DataFlowCallable extends TDataFlowCallable {
205+
Callable asCallable() { this = TCallable(result) }
206+
207+
File asFileScope() { this = TFileScope(result) }
208+
209+
FuncDef getFuncDef() { result = this.asCallable().getFuncDef() }
210+
211+
Function asFunction() { result = this.asCallable().asFunction() }
212+
213+
FuncLit asFuncLit() { result = this.asCallable().asFuncLit() }
214+
215+
SignatureType getType() { result = this.asCallable().getType() }
216+
217+
string toString() {
218+
result = this.asCallable().toString() or
219+
result = "File scope: " + this.asFileScope().toString()
220+
}
221+
222+
predicate hasLocationInfo(
223+
string filepath, int startline, int startcolumn, int endline, int endcolumn
224+
) {
225+
this.asCallable().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) or
226+
this.asFileScope().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
227+
}
228+
}
201229

202230
/** A function call relevant for data flow. */
203231
class DataFlowCall extends Expr {
@@ -214,7 +242,11 @@ class DataFlowCall extends Expr {
214242
ExprNode getNode() { result = call }
215243

216244
/** Gets the enclosing callable of this call. */
217-
DataFlowCallable getEnclosingCallable() { result.getFuncDef() = this.getEnclosingFunction() }
245+
DataFlowCallable getEnclosingCallable() {
246+
result.asCallable().getFuncDef() = this.getEnclosingFunction()
247+
or
248+
not exists(this.getEnclosingFunction()) and result.asFileScope() = this.getFile()
249+
}
218250
}
219251

220252
/** Holds if `e` is an expression that always has the same Boolean value `val`. */

0 commit comments

Comments
 (0)