Skip to content

Commit ff0384e

Browse files
committed
Use shared lib for params
1 parent 42c256e commit ff0384e

2 files changed

Lines changed: 26 additions & 61 deletions

File tree

go/ql/lib/semmle/go/controlflow/ControlFlowGraphShared.qll

Lines changed: 17 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -139,14 +139,16 @@ module GoCfg {
139139
}
140140

141141
class Parameter extends AstNode {
142-
Parameter() { none() }
142+
Parameter() { this = any(Go::Parameter p).getDeclaration() }
143143

144-
AstNode getPattern() { none() }
144+
AstNode getPattern() { result = this }
145145

146146
Expr getDefaultValue() { none() }
147147
}
148148

149-
Parameter callableGetParameter(Callable c, int index) { none() }
149+
Parameter callableGetParameter(Callable c, int index) {
150+
result = c.(Go::FuncDef).getParameter(index).getDeclaration()
151+
}
150152

151153
Callable getEnclosingCallable(AstNode node) {
152154
result = node.getEnclosingFunction()
@@ -600,14 +602,6 @@ module GoCfg {
600602
tag = "result-read:" + i.toString()
601603
)
602604
or
603-
// Parameter init nodes (on the function body)
604-
exists(int i, Go::FuncDef fd |
605-
n = fd.getBody() and
606-
exists(fd.getBody()) and
607-
exists(fd.getParameter(i)) and
608-
tag = "param-init:" + i.toString()
609-
)
610-
or
611605
// Result-variable zero-initialization (on the function body). This single
612606
// node computes the zero value and writes it to the result variable (see
613607
// `IR::EvalImplicitInitInstruction`); it is the same kind of node as the
@@ -1743,17 +1737,16 @@ module GoCfg {
17431737

17441738
/**
17451739
* Function definition prologue and epilogue:
1746-
* - Prologue: Before(body) → param-init:-1 → param-init:0 → ... when a
1747-
* receiver exists; otherwise it starts at param-init:0. Then
1748-
* zero-init:0 → zero-init:1 → ... → first statement
1740+
* - Prologue: parameters are modelled as native CFG nodes by the shared
1741+
* library (Entry → param → ... → Before(body)). The remaining
1742+
* prologue on Before(body) zero-initializes any named result
1743+
* variables: zero-init:0 → zero-init:1 → ... → first statement.
17491744
* - Epilogue: return → result-read:0 → result-read:1 → ... → result-read:last
17501745
*
17511746
* The last result-read node goes to `NormalExit(fd)` via the shared
17521747
* library's `callableExitStep` hook.
17531748
*/
1754-
private predicate hasFuncDefPrologue(Go::FuncDef fd) {
1755-
exists(fd.getParameter(_)) or exists(fd.getResultVar(_))
1756-
}
1749+
private predicate hasFuncDefPrologue(Go::FuncDef fd) { exists(fd.getResultVar(_)) }
17571750

17581751
private predicate funcDefBodyStart(Go::FuncDef fd, PreControlFlowNode n) {
17591752
n.isBefore(getRankedChild(fd.getBody(), 1))
@@ -1784,47 +1777,14 @@ module GoCfg {
17841777

17851778
private predicate funcDefStep(PreControlFlowNode n1, PreControlFlowNode n2) {
17861779
exists(Go::FuncDef fd | exists(fd.getBody()) |
1787-
// Before(body) → first prologue node, or first body statement if no prologue
1780+
// Before(body) → first result-var zero-init node. Parameters are
1781+
// modelled as native CFG nodes by the shared library and route
1782+
// Entry → param → ... → Before(body) ahead of this point; the
1783+
// no-result-variable case (Before(body) → first statement) is handled
1784+
// by `funcDefBodyStep`.
17881785
n1.isBefore(fd.getBody()) and
1789-
(
1790-
// Has receiver: start with param-init:-1
1791-
exists(fd.getParameter(-1)) and n2.isAdditional(fd.getBody(), "param-init:-1")
1792-
or
1793-
// Has ordinary parameters: start with param-init:0
1794-
not exists(fd.getParameter(-1)) and
1795-
exists(fd.getParameter(0)) and
1796-
n2.isAdditional(fd.getBody(), "param-init:0")
1797-
or
1798-
// No parameters, has result vars: start with zero-init:0
1799-
not exists(fd.getParameter(_)) and
1800-
exists(fd.getResultVar(0)) and
1801-
n2.isAdditional(fd.getBody(), "zero-init:0")
1802-
or
1803-
// No parameters and no result vars: go directly to Before(body)
1804-
not exists(fd.getParameter(_)) and
1805-
not exists(fd.getResultVar(_)) and
1806-
funcDefBodyStart(fd, n2)
1807-
)
1808-
or
1809-
// param-init:i → next: param-init:(i+1), or zero-init:0, or Before(body)
1810-
exists(int i | exists(fd.getParameter(i)) |
1811-
n1.isAdditional(fd.getBody(), "param-init:" + i.toString()) and
1812-
(
1813-
// Next parameter exists
1814-
exists(fd.getParameter(i + 1)) and
1815-
n2.isAdditional(fd.getBody(), "param-init:" + (i + 1).toString())
1816-
or
1817-
// No next parameter, has result vars: go to zero-init:0
1818-
not exists(fd.getParameter(i + 1)) and
1819-
exists(fd.getResultVar(0)) and
1820-
n2.isAdditional(fd.getBody(), "zero-init:0")
1821-
or
1822-
// No next parameter and no result vars: go to Before(body)
1823-
not exists(fd.getParameter(i + 1)) and
1824-
not exists(fd.getResultVar(_)) and
1825-
funcDefBodyStart(fd, n2)
1826-
)
1827-
)
1786+
exists(fd.getResultVar(0)) and
1787+
n2.isAdditional(fd.getBody(), "zero-init:0")
18281788
or
18291789
// zero-init:j → next: zero-init:(j+1), or Before(body).
18301790
// The zero-init node also writes the result variable (see

go/ql/lib/semmle/go/controlflow/IR.qll

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ module IR {
102102
not isInBooleanCondContext(e) and
103103
this.isAfter(e)
104104
)
105+
or
106+
// A named parameter is represented by a single CFG node (the merged
107+
// "before"/"after" leaf node for its declaration), which hosts the
108+
// initialization write (see `InitParameterInstruction`).
109+
this.isBefore(any(FuncDef fd).getParameter(_).getDeclaration())
105110
}
106111

107112
/** Holds if this instruction reads the value of variable or constant `v`. */
@@ -982,7 +987,7 @@ module IR {
982987
FuncDef fd;
983988

984989
InitParameterInstruction() {
985-
this.isAdditional(fd.getBody(), "param-init:" + idx.toString()) and
990+
this.isBefore(parm.getDeclaration()) and
986991
parm = fd.getParameter(idx)
987992
}
988993

@@ -1105,7 +1110,7 @@ module IR {
11051110
)
11061111
or
11071112
exists(FuncDef fd, int idx |
1108-
write.isAdditional(fd.getBody(), "param-init:" + idx.toString()) and
1113+
write.isBefore(fd.getParameter(idx).getDeclaration()) and
11091114
lhs = fd.getParameter(idx).getDeclaration()
11101115
)
11111116
or
@@ -1339,7 +1344,7 @@ module IR {
13391344
*/
13401345
InitParameterInstruction initRecvInstruction(ReceiverVariable r) {
13411346
exists(FuncDef fd, int i |
1342-
fd.getParameter(i) = r and result.isAdditional(fd.getBody(), "param-init:" + i.toString())
1347+
fd.getParameter(i) = r and result.isBefore(fd.getParameter(i).getDeclaration())
13431348
)
13441349
}
13451350

@@ -1348,7 +1353,7 @@ module IR {
13481353
*/
13491354
InitParameterInstruction initParamInstruction(Parameter p) {
13501355
exists(FuncDef fd, int i |
1351-
fd.getParameter(i) = p and result.isAdditional(fd.getBody(), "param-init:" + i.toString())
1356+
fd.getParameter(i) = p and result.isBefore(fd.getParameter(i).getDeclaration())
13521357
)
13531358
}
13541359

0 commit comments

Comments
 (0)