File tree Expand file tree Collapse file tree 2 files changed +32
-7
lines changed
go/ql/lib/semmle/go/dataflow/internal Expand file tree Collapse file tree 2 files changed +32
-7
lines changed Original file line number Diff line number Diff line change @@ -134,6 +134,10 @@ class ArgumentPosition extends int {
134
134
pragma [ inline]
135
135
predicate parameterMatch ( ParameterPosition ppos , ArgumentPosition apos ) { ppos = apos }
136
136
137
+ private predicate isInterfaceMethod ( Method c ) {
138
+ c .getReceiverBaseType ( ) .getUnderlyingType ( ) instanceof InterfaceType
139
+ }
140
+
137
141
/**
138
142
* Holds if `call` is passing `arg` to param `p` in any circumstance except passing
139
143
* a receiver parameter to a concrete method.
@@ -147,6 +151,17 @@ predicate golangSpecificParamArgFilter(
147
151
or
148
152
p instanceof DataFlow:: SummarizedParameterNode
149
153
or
150
- not call .getNode ( ) .( DataFlow:: CallNode ) .getReceiver ( ) .getType ( ) .getUnderlyingType ( ) instanceof
151
- InterfaceType
154
+ not isInterfaceMethod ( call .getNode ( )
155
+ .( DataFlow:: CallNode )
156
+ .getACalleeWithoutVirtualDispatch ( )
157
+ .asFunction ( ) )
158
+ }
159
+
160
+ predicate foo ( DataFlowCall call , DataFlow:: Node rec0 ) {
161
+ exists ( DataFlow:: Node rec | rec = call .getNode ( ) .( DataFlow:: CallNode ) .getReceiver ( ) |
162
+ rec = rec0 and rec .getType ( ) .getUnderlyingType ( ) instanceof InterfaceType
163
+ ) and
164
+ not exists ( Function callTarget | callTarget = call .getNode ( ) .( DataFlow:: CallNode ) .getTarget ( ) |
165
+ not isInterfaceMethod ( callTarget )
166
+ )
152
167
}
Original file line number Diff line number Diff line change @@ -489,13 +489,9 @@ module Public {
489
489
* interface type.
490
490
*/
491
491
Callable getACalleeIncludingExternals ( ) {
492
- result . asFunction ( ) = this .getTarget ( )
492
+ result = this .getACalleeWithoutVirtualDispatch ( )
493
493
or
494
494
exists ( DataFlow:: Node calleeSource | calleeSource = this .getACalleeSource ( ) |
495
- result .asFuncLit ( ) = calleeSource .asExpr ( )
496
- or
497
- calleeSource = result .asFunction ( ) .getARead ( )
498
- or
499
495
exists ( Method declared , Method actual |
500
496
calleeSource = declared .getARead ( ) and
501
497
actual .implements ( declared ) and
@@ -510,6 +506,20 @@ module Public {
510
506
*/
511
507
FuncDef getACallee ( ) { result = this .getACalleeIncludingExternals ( ) .getFuncDef ( ) }
512
508
509
+ /**
510
+ * As `getACalleeIncludingExternals`, except excluding external functions (those for which
511
+ * we lack a definition, such as standard library functions).
512
+ */
513
+ Callable getACalleeWithoutVirtualDispatch ( ) {
514
+ result .asFunction ( ) = this .getTarget ( )
515
+ or
516
+ exists ( DataFlow:: Node calleeSource | calleeSource = this .getACalleeSource ( ) |
517
+ result .asFuncLit ( ) = calleeSource .asExpr ( )
518
+ or
519
+ calleeSource = result .asFunction ( ) .getARead ( )
520
+ )
521
+ }
522
+
513
523
/**
514
524
* Gets the name of the function, method or variable that is being called.
515
525
*
You can’t perform that action at this time.
0 commit comments