From 59498f53f05dd35e569cba6e6e1cce14d2db5a62 Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Fri, 3 Jan 2020 13:57:36 +0000 Subject: [PATCH 1/3] Move `FuncDec.getACall` into `FuncDecl`. Also changes the result from a `CallExpr` to a `CallNode` for consistency with `Function.getACall`. --- ql/src/semmle/go/Decls.qll | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/ql/src/semmle/go/Decls.qll b/ql/src/semmle/go/Decls.qll index 4ab2933da83..a119daf27fd 100644 --- a/ql/src/semmle/go/Decls.qll +++ b/ql/src/semmle/go/Decls.qll @@ -130,6 +130,13 @@ class FuncDef extends @funcdef, StmtParent, ExprParent { Parameter getAParameter() { result.getDeclaration() = getTypeExpr().getAParameterDecl().getNameExpr(_) } + + /** + * Gets a call to this function. + */ + DataFlow::CallNode getACall() { + result.getACallee() = this + } } /** @@ -151,9 +158,6 @@ class FuncDecl extends @funcdecl, Decl, Documentable, FuncDef { /** Gets the function declared by this function declaration. */ DeclaredFunction getFunction() { this = result.getDecl() } - /** Gets a (possibly virtual) call to this function. */ - CallExpr getACall() { this = result.getACallee() } - override string toString() { result = "function declaration" } } From bb4052a574d9e683497114256f72a6352b8ad3b6 Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Fri, 3 Jan 2020 13:57:58 +0000 Subject: [PATCH 2/3] Generalise result type of `getACallee`. --- ql/src/semmle/go/Expr.qll | 8 ++++---- ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ql/src/semmle/go/Expr.qll b/ql/src/semmle/go/Expr.qll index 36729f67396..0e1080e1829 100644 --- a/ql/src/semmle/go/Expr.qll +++ b/ql/src/semmle/go/Expr.qll @@ -473,15 +473,15 @@ class CallExpr extends CallOrConversionExpr { Function getTarget() { this = result.getACallExpr() } /** - * Gets the declaration of a possible target of this call. + * Gets the definition of a possible target of this call. * * For non-virtual calls, there is at most one possible call target (but there may be none if the * target has no declaration). * - * For virtual calls, we look up possible targets in all types that implement the receiver interface - * type. + * For virtual calls, we look up possible targets in all types that implement the receiver + * interface type. */ - FuncDecl getACallee() { + FuncDef getACallee() { result = getTarget().(DeclaredFunction).getDecl() or exists(SelectorExpr sel, InterfaceType declaredRecv, Type actualRecv | diff --git a/ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll b/ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll index 434b3808aa0..211b8235aea 100644 --- a/ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll +++ b/ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll @@ -272,8 +272,8 @@ class CallNode extends ExprNode { /** Gets the declared target of this call */ Function getTarget() { result = expr.getTarget() } - /** Get the declaration of a possible target of this call. See `CallExpr.getACallee`. */ - FuncDecl getACallee() { result = expr.getACallee() } + /** Get the definition of a possible target of this call. See `CallExpr.getACallee`. */ + FuncDef getACallee() { result = expr.getACallee() } /** Gets the name of the function or method being called, if it can be determined. */ string getCalleeName() { result = expr.getTarget().getName() } From 638fe07da0895ca894bf82815994828fc4245f8a Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Fri, 3 Jan 2020 13:58:13 +0000 Subject: [PATCH 3/3] Move `getReceiver` from `MethodCallNode` to `CallNode`. --- .../semmle/go/dataflow/internal/DataFlowUtil.qll | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll b/ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll index 211b8235aea..69e1383187f 100644 --- a/ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll +++ b/ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll @@ -320,6 +320,13 @@ class CallNode extends ExprNode { * variant `getResult(i)` for such calls. */ Node getResult() { not getType() instanceof TupleType and result = this } + + /** Gets the data flow node corresponding to the receiver of this call, if any. */ + Node getReceiver() { + exists(SelectorExpr s | exprNode(s).getASuccessor*() = this.getCalleeNode() | + result = exprNode(s.getBase()) + ) + } } /** A data flow node that represents a call to a method. */ @@ -329,13 +336,6 @@ class MethodCallNode extends CallNode { override Method getTarget() { result = expr.getTarget() } override MethodDecl getACallee() { result = expr.getACallee() } - - /** Gets the data flow node corresponding to the receiver of this call. */ - Node getReceiver() { - exists(SelectorExpr s | exprNode(s).getASuccessor*() = this.getCalleeNode() | - result = exprNode(s.getBase()) - ) - } } /** A representation of a receiver initialization. */