Skip to content

Commit de8794e

Browse files
committed
Make MethodCallNode char pred more accurate
When a function is assigned to a variable and called through that variable then we previously didn't realise it was a function. With this change we try use local flow to determine if the function being called is a method.
1 parent d41d2bc commit de8794e

File tree

3 files changed

+12
-8
lines changed

3 files changed

+12
-8
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: fix
3+
---
4+
* The definition of `DataFlow::MethodCallNode` has been expanded to include `DataFlow::CallNode`s where what is being called is a variable that has a method assigned to it within the calling function. This means we can now follow data flow into the receiver of such a method call.

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -631,9 +631,9 @@ module Public {
631631

632632
/** A data flow node that represents a call to a method. */
633633
class MethodCallNode extends CallNode {
634-
MethodCallNode() { expr.getTarget() instanceof Method }
634+
MethodCallNode() { getACalleeSource(this) instanceof MethodReadNode }
635635

636-
override Method getTarget() { result = expr.getTarget() }
636+
override Method getTarget() { result = getACalleeSource(this).(MethodReadNode).getMethod() }
637637

638638
override MethodDecl getACallee() { result = super.getACallee() }
639639
}

go/ql/test/library-tests/semmle/go/dataflow/GenericFunctionsAndTypes/generictypesandmethods.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func main() {
5151
gs1 := GenericStruct1[string]{""}
5252
gs1.Field = source()
5353
f := gs1.Getter
54-
sink(f()) // $ MISSING: hasValueFlow="call to f"
54+
sink(f()) // $ hasValueFlow="call to f"
5555
}
5656
{
5757
gs1 := GenericStruct1[string]{""}
@@ -62,7 +62,7 @@ func main() {
6262
gs1 := GenericStruct1[string]{""}
6363
f := gs1.Setter
6464
f(source())
65-
sink(gs1.Field) // $ MISSING: hasValueFlow="selection of Field"
65+
sink(gs1.Field) // $ hasValueFlow="selection of Field"
6666
}
6767

6868
{
@@ -87,7 +87,7 @@ func main() {
8787
gs2 := GenericStruct2[string, string]{"", ""}
8888
gs2.Field1 = source()
8989
f := gs2.Getter1
90-
sink(f()) // $ MISSING: hasValueFlow="call to f"
90+
sink(f()) // $ hasValueFlow="call to f"
9191
}
9292
{
9393
gs2 := GenericStruct2[string, string]{"", ""}
@@ -98,7 +98,7 @@ func main() {
9898
gs2 := GenericStruct2[string, string]{"", ""}
9999
f := gs2.Setter1
100100
f(source())
101-
sink(gs2.Field1) // $ MISSING: hasValueFlow="selection of Field1"
101+
sink(gs2.Field1) // $ hasValueFlow="selection of Field1"
102102
}
103103

104104
{
@@ -123,7 +123,7 @@ func main() {
123123
gs2 := GenericStruct2[string, string]{"", ""}
124124
gs2.Field2 = source()
125125
f := gs2.Getter2
126-
sink(f()) // $ MISSING: hasValueFlow="call to f"
126+
sink(f()) // $ hasValueFlow="call to f"
127127
}
128128
{
129129
gs2 := GenericStruct2[string, string]{"", ""}
@@ -134,6 +134,6 @@ func main() {
134134
gs2 := GenericStruct2[string, string]{"", ""}
135135
f := gs2.Setter2
136136
f(source())
137-
sink(gs2.Field2) // $ MISSING: hasValueFlow="selection of Field2"
137+
sink(gs2.Field2) // $ hasValueFlow="selection of Field2"
138138
}
139139
}

0 commit comments

Comments
 (0)