From b7a830593d166f06a3ccd27ea25a88ab79b5d78e Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Wed, 15 Jan 2020 10:22:29 +0000 Subject: [PATCH] Correctly create extract nodes for `return`s where we cannot infer the type of the returned expression, but know from context that it must be a tuple type. --- ql/src/semmle/go/controlflow/ControlFlowGraphImpl.qll | 11 ++++++++--- .../RedundantCode/DeadStoreOfLocal/main.go | 4 ++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ql/src/semmle/go/controlflow/ControlFlowGraphImpl.qll b/ql/src/semmle/go/controlflow/ControlFlowGraphImpl.qll index 3dc5849a367..cd679dd6c63 100644 --- a/ql/src/semmle/go/controlflow/ControlFlowGraphImpl.qll +++ b/ql/src/semmle/go/controlflow/ControlFlowGraphImpl.qll @@ -114,9 +114,14 @@ newtype TControlFlowNode = ) or // in a return statement `return f()` where `f` has multiple return values - exists(ReturnStmt ret, CallExpr call | s = ret | - call = ret.getExpr().stripParens() and - exists(call.getType().(TupleType).getComponentType(i)) + exists(ReturnStmt ret, SignatureType rettp | + s = ret and + // the return statement has a single expression + exists(ret.getExpr()) and + // but the enclosing function has multiple results + rettp = ret.getEnclosingFunction().getType() and + rettp.getNumResult() > 1 and + exists(rettp.getResultType(i)) ) or // in a call `f(g())` where `g` has multiple return values diff --git a/ql/test/query-tests/RedundantCode/DeadStoreOfLocal/main.go b/ql/test/query-tests/RedundantCode/DeadStoreOfLocal/main.go index 3bb3c390ae0..31062a18f98 100644 --- a/ql/test/query-tests/RedundantCode/DeadStoreOfLocal/main.go +++ b/ql/test/query-tests/RedundantCode/DeadStoreOfLocal/main.go @@ -31,3 +31,7 @@ func test2(x int) (int, int) { z := x % (1) return z, y % 13 } + +func test3() (x int, y int) { + return unknownFunction() +}