diff --git a/go/ql/lib/semmle/go/controlflow/IR.qll b/go/ql/lib/semmle/go/controlflow/IR.qll index 6c7a0c682b53..1a56dfcf2dc9 100644 --- a/go/ql/lib/semmle/go/controlflow/IR.qll +++ b/go/ql/lib/semmle/go/controlflow/IR.qll @@ -718,10 +718,6 @@ module IR { predicate extractsElement(Instruction base, int idx) { base = this.getBase() and idx = i } override Type getResultType() { - exists(CallExpr c | this.getBase() = evalExprInstruction(c) | - result = c.getTarget().getResultType(i) - ) - or exists(Expr e | this.getBase() = evalExprInstruction(e) | result = e.getType().(TupleType).getComponentType(pragma[only_bind_into](i)) ) diff --git a/go/ql/test/library-tests/semmle/go/IR/test.expected b/go/ql/test/library-tests/semmle/go/IR/test.expected index df2f83e33931..c42cdaa9932f 100644 --- a/go/ql/test/library-tests/semmle/go/IR/test.expected +++ b/go/ql/test/library-tests/semmle/go/IR/test.expected @@ -1,6 +1,10 @@ -| test.go:9:2:9:16 | ... := ...[0] | file://:0:0:0:0 | bool | -| test.go:9:2:9:16 | ... := ...[1] | file://:0:0:0:0 | bool | -| test.go:15:2:15:20 | ... := ...[0] | file://:0:0:0:0 | string | -| test.go:15:2:15:20 | ... := ...[1] | file://:0:0:0:0 | bool | -| test.go:21:2:21:22 | ... := ...[0] | file://:0:0:0:0 | string | -| test.go:21:2:21:22 | ... := ...[1] | file://:0:0:0:0 | bool | +| test.go:9:2:9:16 | ... := ...[0] | test.go:9:13:9:16 | <-... | 0 | file://:0:0:0:0 | bool | +| test.go:9:2:9:16 | ... := ...[1] | test.go:9:13:9:16 | <-... | 1 | file://:0:0:0:0 | bool | +| test.go:15:2:15:20 | ... := ...[0] | test.go:15:13:15:20 | index expression | 0 | file://:0:0:0:0 | string | +| test.go:15:2:15:20 | ... := ...[1] | test.go:15:13:15:20 | index expression | 1 | file://:0:0:0:0 | bool | +| test.go:21:2:21:22 | ... := ...[0] | test.go:21:13:21:22 | type assertion | 0 | file://:0:0:0:0 | string | +| test.go:21:2:21:22 | ... := ...[1] | test.go:21:13:21:22 | type assertion | 1 | file://:0:0:0:0 | bool | +| test.go:29:2:29:7 | call to f[0] | test.go:29:4:29:6 | call to g | 0 | file://:0:0:0:0 | int | +| test.go:29:2:29:7 | call to f[1] | test.go:29:4:29:6 | call to g | 1 | file://:0:0:0:0 | int | +| test.go:33:2:33:7 | call to f[0] | test.go:33:4:33:6 | call to v | 0 | file://:0:0:0:0 | int | +| test.go:33:2:33:7 | call to f[1] | test.go:33:4:33:6 | call to v | 1 | file://:0:0:0:0 | int | diff --git a/go/ql/test/library-tests/semmle/go/IR/test.go b/go/ql/test/library-tests/semmle/go/IR/test.go index de0d567dc3ad..d048632b95b7 100644 --- a/go/ql/test/library-tests/semmle/go/IR/test.go +++ b/go/ql/test/library-tests/semmle/go/IR/test.go @@ -21,3 +21,14 @@ func testTypeAssert() { got, ok := i.(string) fmt.Printf("%v %v", got, ok) } + +func f(x, y int) {} +func g() (int, int) { return 0, 0 } + +func testNestedFunctionCalls() { + f(g()) + + // Edge case: when we call a function from a variable, `getTarget()` is not defined + v := g + f(v()) +} diff --git a/go/ql/test/library-tests/semmle/go/IR/test.ql b/go/ql/test/library-tests/semmle/go/IR/test.ql index 1644bd5b2efe..2c4fa43eac00 100644 --- a/go/ql/test/library-tests/semmle/go/IR/test.ql +++ b/go/ql/test/library-tests/semmle/go/IR/test.ql @@ -1,4 +1,5 @@ import go -from IR::ExtractTupleElementInstruction extract -select extract, extract.getResultType() +from IR::ExtractTupleElementInstruction extract, IR::Instruction base, int idx, Type resultType +where extract.extractsElement(base, idx) and resultType = extract.getResultType() +select extract, base, idx, resultType