From 68bb7b02febf10bcc9bc10ce4a95273204de5a31 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 1 Oct 2020 14:06:52 +0100 Subject: [PATCH] Refactor DataFlow::FunctionNode as a concrete class This makes it easier to refine FunctionNode without having to define abstract members. --- .../go/dataflow/internal/DataFlowUtil.qll | 49 ++++++++++++++++--- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll b/ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll index ac23d4f2c..4b7f8e623 100644 --- a/ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll +++ b/ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll @@ -216,10 +216,43 @@ class SsaNode extends Node, MkSsaNode { } } +private module FunctionNode { + /** A function, viewed as a node in a data flow graph. */ + abstract class Range extends Node { + /** Gets the `i`th parameter of this function. */ + abstract ParameterNode getParameter(int i); + + /** Gets the name of this function, if it has one. */ + abstract string getName(); + + /** + * Gets the dataflow node holding the value of the receiver, if any. + */ + abstract ReceiverNode getReceiver(); + + /** + * Gets a value returned by the given function via a return statement or an assignment to a + * result variable. + */ + abstract ResultNode getAResult(); + + /** + * Gets the function entity this node corresponds to. + * + * Note that this predicate has no result for function literals. + */ + Function getFunction() { none() } + } +} + /** A function, viewed as a node in a data flow graph. */ -abstract class FunctionNode extends Node { +class FunctionNode extends Node { + FunctionNode::Range self; + + FunctionNode() { this = self } + /** Gets the `i`th parameter of this function. */ - abstract ParameterNode getParameter(int i); + ParameterNode getParameter(int i) { result = self.getParameter(i) } /** Gets a parameter of this function. */ ParameterNode getAParameter() { result = this.getParameter(_) } @@ -228,18 +261,18 @@ abstract class FunctionNode extends Node { int getNumParameter() { result = count(this.getAParameter()) } /** Gets the name of this function, if it has one. */ - abstract string getName(); + string getName() { result = self.getName() } /** * Gets the dataflow node holding the value of the receiver, if any. */ - abstract ReceiverNode getReceiver(); + ReceiverNode getReceiver() { result = self.getReceiver() } /** * Gets a value returned by the given function via a return statement or an assignment to a * result variable. */ - abstract ResultNode getAResult(); + ResultNode getAResult() { result = self.getAResult() } /** * Gets the data-flow node corresponding to the `i`th result of this function. @@ -251,11 +284,11 @@ abstract class FunctionNode extends Node { * * Note that this predicate has no result for function literals. */ - Function getFunction() { none() } + Function getFunction() { result = self.getFunction() } } /** A representation of a function that is declared in the module scope. */ -class GlobalFunctionNode extends FunctionNode, MkGlobalFunctionNode { +class GlobalFunctionNode extends FunctionNode::Range, MkGlobalFunctionNode { Function func; GlobalFunctionNode() { this = MkGlobalFunctionNode(func) } @@ -284,7 +317,7 @@ class GlobalFunctionNode extends FunctionNode, MkGlobalFunctionNode { } /** A representation of the function that is defined by a function literal. */ -class FuncLitNode extends FunctionNode, ExprNode { +class FuncLitNode extends FunctionNode::Range, ExprNode { override FuncLit expr; override ParameterNode getParameter(int i) { result = parameterNode(expr.getParameter(i)) }