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" } } 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..69e1383187f 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() } @@ -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. */