Skip to content

Commit 992a0b5

Browse files
committed
Unify result-zero-init and zero-init node kinds
1 parent c8f81bc commit 992a0b5

7 files changed

Lines changed: 62 additions & 100 deletions

File tree

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

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ module GoCfg {
512512
not extractNodeCondition(n, i)
513513
or
514514
// A `ValueSpec` without an initializer is written by its `zero-init`
515-
// node directly (see `IR::InitVariableInstruction`), and a
515+
// node directly (see `IR::EvalImplicitInitInstruction`), and a
516516
// tuple-destructuring declaration (`var x, y = f()`) is written by its
517517
// `extract` node; only specs with a per-name initializer emit
518518
// `assign:i`.
@@ -570,15 +570,16 @@ module GoCfg {
570570
tag = "param-init:" + i.toString()
571571
)
572572
or
573-
// Result variable zero init + init (on the function body). This single
573+
// Result-variable zero-initialization (on the function body). This single
574574
// node computes the zero value and writes it to the result variable (see
575-
// `IR::InitResultInstruction`).
575+
// `IR::EvalImplicitInitInstruction`); it is the same kind of node as the
576+
// `zero-init` of an uninitialised local variable.
576577
exists(int i, Go::FuncDef fd |
577578
n = fd.getBody() and
578579
exists(fd.getBody()) and
579580
exists(fd.getResultVar(i)) and
580581
exists(fd.getResultVar(i).(Go::ResultVariable).getFunction().getBody()) and
581-
tag = "result-zero-init:" + i.toString()
582+
tag = "zero-init:" + i.toString()
582583
)
583584
or
584585
// Implicit deref
@@ -1710,7 +1711,7 @@ module GoCfg {
17101711
* Function definition prologue and epilogue:
17111712
* - Prologue: Before(body) → param-init:-1 → param-init:0 → ... when a
17121713
* receiver exists; otherwise it starts at param-init:0. Then
1713-
* result-zero-init:0 → result-zero-init:1 → ... → first statement
1714+
* zero-init:0 → zero-init:1 → ... → first statement
17141715
* - Epilogue: return → result-read:0 → result-read:1 → ... → result-read:last
17151716
*
17161717
* The last result-read node goes to `NormalExit(fd)` via the shared
@@ -1760,29 +1761,29 @@ module GoCfg {
17601761
exists(fd.getParameter(0)) and
17611762
n2.isAdditional(fd.getBody(), "param-init:0")
17621763
or
1763-
// No parameters, has result vars: start with result-zero-init:0
1764+
// No parameters, has result vars: start with zero-init:0
17641765
not exists(fd.getParameter(_)) and
17651766
exists(fd.getResultVar(0)) and
1766-
n2.isAdditional(fd.getBody(), "result-zero-init:0")
1767+
n2.isAdditional(fd.getBody(), "zero-init:0")
17671768
or
17681769
// No parameters and no result vars: go directly to Before(body)
17691770
not exists(fd.getParameter(_)) and
17701771
not exists(fd.getResultVar(_)) and
17711772
funcDefBodyStart(fd, n2)
17721773
)
17731774
or
1774-
// param-init:i → next: param-init:(i+1), or result-zero-init:0, or Before(body)
1775+
// param-init:i → next: param-init:(i+1), or zero-init:0, or Before(body)
17751776
exists(int i | exists(fd.getParameter(i)) |
17761777
n1.isAdditional(fd.getBody(), "param-init:" + i.toString()) and
17771778
(
17781779
// Next parameter exists
17791780
exists(fd.getParameter(i + 1)) and
17801781
n2.isAdditional(fd.getBody(), "param-init:" + (i + 1).toString())
17811782
or
1782-
// No next parameter, has result vars: go to result-zero-init:0
1783+
// No next parameter, has result vars: go to zero-init:0
17831784
not exists(fd.getParameter(i + 1)) and
17841785
exists(fd.getResultVar(0)) and
1785-
n2.isAdditional(fd.getBody(), "result-zero-init:0")
1786+
n2.isAdditional(fd.getBody(), "zero-init:0")
17861787
or
17871788
// No next parameter and no result vars: go to Before(body)
17881789
not exists(fd.getParameter(i + 1)) and
@@ -1791,15 +1792,15 @@ module GoCfg {
17911792
)
17921793
)
17931794
or
1794-
// result-zero-init:j → next: result-zero-init:(j+1), or Before(body).
1795+
// zero-init:j → next: zero-init:(j+1), or Before(body).
17951796
// The zero-init node also writes the result variable (see
1796-
// `IR::InitResultInstruction`), so there is no separate result-init node.
1797+
// `IR::EvalImplicitInitInstruction`), so there is no separate result-init node.
17971798
exists(int j | exists(fd.getResultVar(j)) |
1798-
n1.isAdditional(fd.getBody(), "result-zero-init:" + j.toString()) and
1799+
n1.isAdditional(fd.getBody(), "zero-init:" + j.toString()) and
17991800
(
18001801
// Next result var exists
18011802
exists(fd.getResultVar(j + 1)) and
1802-
n2.isAdditional(fd.getBody(), "result-zero-init:" + (j + 1).toString())
1803+
n2.isAdditional(fd.getBody(), "zero-init:" + (j + 1).toString())
18031804
or
18041805
// No next result var: go to Before(body)
18051806
not exists(fd.getResultVar(j + 1)) and

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

Lines changed: 12 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ module IR {
642642
exists(assgn.(Assignment).getLhs(i))
643643
or
644644
// A `ValueSpec` without an initializer (`var x int`) is written by its
645-
// `zero-init` node directly (see `InitVariableInstruction`), so only
645+
// `zero-init` node directly (see `EvalImplicitInitInstruction`), so only
646646
// specs *with* an initializer produce an `assign` node.
647647
exists(assgn.(ValueSpec).getNameExpr(i)) and
648648
exists(assgn.(ValueSpec).getAnInit())
@@ -786,10 +786,13 @@ module IR {
786786
}
787787

788788
/**
789-
* An instruction that computes the zero value to which a variable without an initializer
790-
* expression is initialized.
789+
* An instruction initializing a variable declared without an initializer
790+
* (a local `var x int`, or a named function result) to its zero value.
791+
*
792+
* The zero-value instruction performs the write of the variable directly,
793+
* rather than feeding a separate write node.
791794
*/
792-
class EvalImplicitInitInstruction extends Instruction {
795+
class EvalImplicitInitInstruction extends WriteInstruction {
793796
ValueEntity v;
794797

795798
EvalImplicitInitInstruction() {
@@ -799,11 +802,13 @@ module IR {
799802
)
800803
or
801804
exists(FuncDef fd, int idx |
802-
this.isAdditional(fd.getBody(), "result-zero-init:" + idx.toString()) and
805+
this.isAdditional(fd.getBody(), "zero-init:" + idx.toString()) and
803806
v = fd.getResultVar(idx)
804807
)
805808
}
806809

810+
override Instruction getRhs() { result = this }
811+
807812
override Type getResultType() { result = v.getType() }
808813

809814
override ControlFlow::Root getRoot() { result.isRootOf(v.getDeclaration()) }
@@ -993,50 +998,6 @@ module IR {
993998
override ControlFlow::Root getRoot() { result = parm.getFunction() }
994999
}
9951000

996-
/**
997-
* An instruction initializing a result variable to its zero value.
998-
*
999-
* This is the same node as the `EvalImplicitInitInstruction` that computes the
1000-
* zero value: the zero-value instruction performs the write of the result
1001-
* variable directly, rather than feeding a separate write node.
1002-
*/
1003-
class InitResultInstruction extends WriteInstruction {
1004-
ResultVariable res;
1005-
int idx;
1006-
FuncDef fd;
1007-
1008-
InitResultInstruction() {
1009-
this.isAdditional(fd.getBody(), "result-zero-init:" + idx.toString()) and
1010-
res = fd.getResultVar(idx)
1011-
}
1012-
1013-
override Instruction getRhs() { result = this }
1014-
1015-
override ControlFlow::Root getRoot() { result = res.getFunction() }
1016-
}
1017-
1018-
/**
1019-
* An instruction initializing a variable declared without an initializer
1020-
* (`var x int`) to its zero value.
1021-
*
1022-
* This is the same node as the `EvalImplicitInitInstruction` that computes the
1023-
* zero value: the zero-value instruction performs the write of the variable
1024-
* directly, rather than feeding a separate write node.
1025-
*/
1026-
class InitVariableInstruction extends WriteInstruction {
1027-
ValueSpec spec;
1028-
int idx;
1029-
1030-
InitVariableInstruction() {
1031-
this.isAdditional(spec, "zero-init:" + idx.toString()) and
1032-
exists(spec.getNameExpr(idx))
1033-
}
1034-
1035-
override Instruction getRhs() { result = this }
1036-
1037-
override ControlFlow::Root getRoot() { result.isRootOf(spec) }
1038-
}
1039-
10401001
/** An instruction that gets the next key-value pair in a range loop. */
10411002
class GetNextEntryInstruction extends Instruction {
10421003
RangeElementExpr p;
@@ -1152,7 +1113,7 @@ module IR {
11521113
)
11531114
or
11541115
exists(FuncDef fd, int idx |
1155-
write.isAdditional(fd.getBody(), "result-zero-init:" + idx.toString()) and
1116+
write.isAdditional(fd.getBody(), "zero-init:" + idx.toString()) and
11561117
lhs = fd.getResultVar(idx).getDeclaration()
11571118
)
11581119
or
@@ -1439,7 +1400,7 @@ module IR {
14391400
or
14401401
exists(FuncDef fd, int i |
14411402
fd.getResultVar(i) = v and
1442-
result.isAdditional(fd.getBody(), "result-zero-init:" + i.toString())
1403+
result.isAdditional(fd.getBody(), "zero-init:" + i.toString())
14431404
)
14441405
}
14451406

go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/ControlFlowNode_getASuccessor.expected

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -244,11 +244,11 @@
244244
| epilogues.go:42:1:48:1 | Normal Exit | epilogues.go:42:1:48:1 | Exit |
245245
| epilogues.go:42:1:48:1 | function declaration | epilogues.go:42:1:48:1 | After function declaration |
246246
| epilogues.go:42:51:48:1 | block statement | epilogues.go:42:51:48:1 | param-init:0 block statement |
247-
| epilogues.go:42:51:48:1 | param-init:0 block statement | epilogues.go:42:51:48:1 | result-zero-init:0 block statement |
247+
| epilogues.go:42:51:48:1 | param-init:0 block statement | epilogues.go:42:51:48:1 | zero-init:0 block statement |
248248
| epilogues.go:42:51:48:1 | result-read:0 block statement | epilogues.go:42:51:48:1 | result-read:1 block statement |
249249
| epilogues.go:42:51:48:1 | result-read:1 block statement | epilogues.go:42:1:48:1 | Normal Exit |
250-
| epilogues.go:42:51:48:1 | result-zero-init:0 block statement | epilogues.go:42:51:48:1 | result-zero-init:1 block statement |
251-
| epilogues.go:42:51:48:1 | result-zero-init:1 block statement | epilogues.go:43:2:46:2 | if statement |
250+
| epilogues.go:42:51:48:1 | zero-init:0 block statement | epilogues.go:42:51:48:1 | zero-init:1 block statement |
251+
| epilogues.go:42:51:48:1 | zero-init:1 block statement | epilogues.go:43:2:46:2 | if statement |
252252
| epilogues.go:43:2:46:2 | After if statement | epilogues.go:47:2:47:14 | Before return statement |
253253
| epilogues.go:43:2:46:2 | if statement | epilogues.go:43:5:43:9 | Before ...<... |
254254
| epilogues.go:43:5:43:5 | After x | epilogues.go:43:9:43:9 | Before 0 |
@@ -290,9 +290,9 @@
290290
| epilogues.go:51:1:54:1 | Normal Exit | epilogues.go:51:1:54:1 | Exit |
291291
| epilogues.go:51:1:54:1 | function declaration | epilogues.go:51:1:54:1 | After function declaration |
292292
| epilogues.go:51:38:54:1 | block statement | epilogues.go:51:38:54:1 | param-init:0 block statement |
293-
| epilogues.go:51:38:54:1 | param-init:0 block statement | epilogues.go:51:38:54:1 | result-zero-init:0 block statement |
293+
| epilogues.go:51:38:54:1 | param-init:0 block statement | epilogues.go:51:38:54:1 | zero-init:0 block statement |
294294
| epilogues.go:51:38:54:1 | result-read:0 block statement | epilogues.go:51:1:54:1 | Normal Exit |
295-
| epilogues.go:51:38:54:1 | result-zero-init:0 block statement | epilogues.go:52:2:52:10 | ... = ... |
295+
| epilogues.go:51:38:54:1 | zero-init:0 block statement | epilogues.go:52:2:52:10 | ... = ... |
296296
| epilogues.go:52:2:52:10 | ... = ... | epilogues.go:52:6:52:10 | Before ...+... |
297297
| epilogues.go:52:2:52:10 | After ... = ... | epilogues.go:53:2:53:7 | Before return statement |
298298
| epilogues.go:52:2:52:10 | assign:0 ... = ... | epilogues.go:52:2:52:10 | After ... = ... |
@@ -508,9 +508,9 @@
508508
| epilogues.go:87:1:98:1 | Normal Exit | epilogues.go:87:1:98:1 | Exit |
509509
| epilogues.go:87:1:98:1 | function declaration | epilogues.go:87:1:98:1 | After function declaration |
510510
| epilogues.go:87:42:98:1 | block statement | epilogues.go:87:42:98:1 | param-init:0 block statement |
511-
| epilogues.go:87:42:98:1 | param-init:0 block statement | epilogues.go:87:42:98:1 | result-zero-init:0 block statement |
511+
| epilogues.go:87:42:98:1 | param-init:0 block statement | epilogues.go:87:42:98:1 | zero-init:0 block statement |
512512
| epilogues.go:87:42:98:1 | result-read:0 block statement | epilogues.go:87:1:98:1 | Normal Exit |
513-
| epilogues.go:87:42:98:1 | result-zero-init:0 block statement | epilogues.go:88:2:92:4 | Before defer statement |
513+
| epilogues.go:87:42:98:1 | zero-init:0 block statement | epilogues.go:88:2:92:4 | Before defer statement |
514514
| epilogues.go:88:2:92:4 | After defer statement | epilogues.go:93:2:95:2 | if statement |
515515
| epilogues.go:88:2:92:4 | Before defer statement | epilogues.go:88:8:92:4 | function call |
516516
| epilogues.go:88:2:92:4 | defer statement | epilogues.go:88:2:92:4 | After defer statement |
@@ -605,11 +605,11 @@
605605
| epilogues.go:102:1:110:1 | Normal Exit | epilogues.go:102:1:110:1 | Exit |
606606
| epilogues.go:102:1:110:1 | function declaration | epilogues.go:102:1:110:1 | After function declaration |
607607
| epilogues.go:102:50:110:1 | block statement | epilogues.go:102:50:110:1 | param-init:0 block statement |
608-
| epilogues.go:102:50:110:1 | param-init:0 block statement | epilogues.go:102:50:110:1 | result-zero-init:0 block statement |
608+
| epilogues.go:102:50:110:1 | param-init:0 block statement | epilogues.go:102:50:110:1 | zero-init:0 block statement |
609609
| epilogues.go:102:50:110:1 | result-read:0 block statement | epilogues.go:102:50:110:1 | result-read:1 block statement |
610610
| epilogues.go:102:50:110:1 | result-read:1 block statement | epilogues.go:102:1:110:1 | Normal Exit |
611-
| epilogues.go:102:50:110:1 | result-zero-init:0 block statement | epilogues.go:102:50:110:1 | result-zero-init:1 block statement |
612-
| epilogues.go:102:50:110:1 | result-zero-init:1 block statement | epilogues.go:103:2:103:19 | Before defer statement |
611+
| epilogues.go:102:50:110:1 | zero-init:0 block statement | epilogues.go:102:50:110:1 | zero-init:1 block statement |
612+
| epilogues.go:102:50:110:1 | zero-init:1 block statement | epilogues.go:103:2:103:19 | Before defer statement |
613613
| epilogues.go:103:2:103:19 | After defer statement | epilogues.go:104:2:106:2 | if statement |
614614
| epilogues.go:103:2:103:19 | Before defer statement | epilogues.go:103:8:103:19 | call to epiRecover |
615615
| epilogues.go:103:2:103:19 | defer statement | epilogues.go:103:2:103:19 | After defer statement |
@@ -1275,9 +1275,9 @@
12751275
| exprs.go:49:1:54:1 | Normal Exit | exprs.go:49:1:54:1 | Exit |
12761276
| exprs.go:49:1:54:1 | function declaration | exprs.go:49:1:54:1 | After function declaration |
12771277
| exprs.go:49:30:54:1 | block statement | exprs.go:49:30:54:1 | param-init:0 block statement |
1278-
| exprs.go:49:30:54:1 | param-init:0 block statement | exprs.go:49:30:54:1 | result-zero-init:0 block statement |
1278+
| exprs.go:49:30:54:1 | param-init:0 block statement | exprs.go:49:30:54:1 | zero-init:0 block statement |
12791279
| exprs.go:49:30:54:1 | result-read:0 block statement | exprs.go:49:1:54:1 | Normal Exit |
1280-
| exprs.go:49:30:54:1 | result-zero-init:0 block statement | exprs.go:50:2:52:2 | for statement |
1280+
| exprs.go:49:30:54:1 | zero-init:0 block statement | exprs.go:50:2:52:2 | for statement |
12811281
| exprs.go:50:2:52:2 | After for statement | exprs.go:53:2:53:7 | Before return statement |
12821282
| exprs.go:50:2:52:2 | [LoopHeader] for statement | exprs.go:50:27:50:29 | Before increment statement |
12831283
| exprs.go:50:2:52:2 | for statement | exprs.go:50:6:50:11 | ... := ... |
@@ -2115,9 +2115,9 @@
21152115
| main.go:47:1:50:1 | Entry | main.go:47:25:50:1 | block statement |
21162116
| main.go:47:1:50:1 | Normal Exit | main.go:47:1:50:1 | Exit |
21172117
| main.go:47:1:50:1 | function declaration | main.go:47:1:50:1 | After function declaration |
2118-
| main.go:47:25:50:1 | block statement | main.go:47:25:50:1 | result-zero-init:0 block statement |
2118+
| main.go:47:25:50:1 | block statement | main.go:47:25:50:1 | zero-init:0 block statement |
21192119
| main.go:47:25:50:1 | result-read:0 block statement | main.go:47:1:50:1 | Normal Exit |
2120-
| main.go:47:25:50:1 | result-zero-init:0 block statement | main.go:48:2:48:12 | ... = ... |
2120+
| main.go:47:25:50:1 | zero-init:0 block statement | main.go:48:2:48:12 | ... = ... |
21212121
| main.go:48:2:48:12 | ... = ... | main.go:48:11:48:12 | Before 42 |
21222122
| main.go:48:2:48:12 | After ... = ... | main.go:49:2:49:7 | Before return statement |
21232123
| main.go:48:2:48:12 | assign:0 ... = ... | main.go:48:2:48:12 | After ... = ... |
@@ -2131,9 +2131,9 @@
21312131
| main.go:52:1:54:1 | Entry | main.go:52:26:54:1 | block statement |
21322132
| main.go:52:1:54:1 | Normal Exit | main.go:52:1:54:1 | Exit |
21332133
| main.go:52:1:54:1 | function declaration | main.go:52:1:54:1 | After function declaration |
2134-
| main.go:52:26:54:1 | block statement | main.go:52:26:54:1 | result-zero-init:0 block statement |
2134+
| main.go:52:26:54:1 | block statement | main.go:52:26:54:1 | zero-init:0 block statement |
21352135
| main.go:52:26:54:1 | result-read:0 block statement | main.go:52:1:54:1 | Normal Exit |
2136-
| main.go:52:26:54:1 | result-zero-init:0 block statement | main.go:53:2:53:7 | Before return statement |
2136+
| main.go:52:26:54:1 | zero-init:0 block statement | main.go:53:2:53:7 | Before return statement |
21372137
| main.go:53:2:53:7 | Before return statement | main.go:53:2:53:7 | return statement |
21382138
| main.go:53:2:53:7 | return statement | main.go:52:26:54:1 | result-read:0 block statement |
21392139
| main.go:56:1:64:1 | After function declaration | main.go:66:1:90:1 | Before function declaration |
@@ -2142,9 +2142,9 @@
21422142
| main.go:56:1:64:1 | Normal Exit | main.go:56:1:64:1 | Exit |
21432143
| main.go:56:1:64:1 | function declaration | main.go:56:1:64:1 | After function declaration |
21442144
| main.go:56:38:64:1 | block statement | main.go:56:38:64:1 | param-init:0 block statement |
2145-
| main.go:56:38:64:1 | param-init:0 block statement | main.go:56:38:64:1 | result-zero-init:0 block statement |
2145+
| main.go:56:38:64:1 | param-init:0 block statement | main.go:56:38:64:1 | zero-init:0 block statement |
21462146
| main.go:56:38:64:1 | result-read:0 block statement | main.go:56:1:64:1 | Normal Exit |
2147-
| main.go:56:38:64:1 | result-zero-init:0 block statement | main.go:57:2:57:11 | ... = ... |
2147+
| main.go:56:38:64:1 | zero-init:0 block statement | main.go:57:2:57:11 | ... = ... |
21482148
| main.go:57:2:57:11 | ... = ... | main.go:57:11:57:11 | Before 0 |
21492149
| main.go:57:2:57:11 | After ... = ... | main.go:58:2:62:2 | if statement |
21502150
| main.go:57:2:57:11 | assign:0 ... = ... | main.go:57:2:57:11 | After ... = ... |
@@ -2345,11 +2345,11 @@
23452345
| main.go:92:1:96:1 | Entry | main.go:92:36:96:1 | block statement |
23462346
| main.go:92:1:96:1 | Normal Exit | main.go:92:1:96:1 | Exit |
23472347
| main.go:92:1:96:1 | function declaration | main.go:92:1:96:1 | After function declaration |
2348-
| main.go:92:36:96:1 | block statement | main.go:92:36:96:1 | result-zero-init:0 block statement |
2348+
| main.go:92:36:96:1 | block statement | main.go:92:36:96:1 | zero-init:0 block statement |
23492349
| main.go:92:36:96:1 | result-read:0 block statement | main.go:92:36:96:1 | result-read:1 block statement |
23502350
| main.go:92:36:96:1 | result-read:1 block statement | main.go:92:1:96:1 | Normal Exit |
2351-
| main.go:92:36:96:1 | result-zero-init:0 block statement | main.go:92:36:96:1 | result-zero-init:1 block statement |
2352-
| main.go:92:36:96:1 | result-zero-init:1 block statement | main.go:93:2:93:8 | ... := ... |
2351+
| main.go:92:36:96:1 | zero-init:0 block statement | main.go:92:36:96:1 | zero-init:1 block statement |
2352+
| main.go:92:36:96:1 | zero-init:1 block statement | main.go:93:2:93:8 | ... := ... |
23532353
| main.go:93:2:93:8 | ... := ... | main.go:93:7:93:8 | Before 23 |
23542354
| main.go:93:2:93:8 | After ... := ... | main.go:94:2:94:15 | ... = ... |
23552355
| main.go:93:2:93:8 | assign:0 ... := ... | main.go:93:2:93:8 | After ... := ... |

go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@
5151
| main.go:46:44:52:1 | SSA def(vals) | main.go:48:3:48:6 | vals |
5252
| main.go:46:44:52:1 | SSA def(xs) | main.go:47:20:47:21 | xs |
5353
| main.go:46:44:52:1 | param-init:0 block statement | main.go:46:44:52:1 | SSA def(xs) |
54-
| main.go:46:44:52:1 | result-zero-init:0 block statement | main.go:46:44:52:1 | SSA def(keys) |
55-
| main.go:46:44:52:1 | result-zero-init:1 block statement | main.go:46:44:52:1 | SSA def(vals) |
54+
| main.go:46:44:52:1 | zero-init:0 block statement | main.go:46:44:52:1 | SSA def(keys) |
55+
| main.go:46:44:52:1 | zero-init:1 block statement | main.go:46:44:52:1 | SSA def(vals) |
5656
| main.go:47:2:50:2 | SSA def(k) | main.go:49:11:49:11 | k |
5757
| main.go:47:2:50:2 | SSA def(v) | main.go:48:11:48:11 | v |
5858
| main.go:47:2:50:2 | extract:0 range element | main.go:47:2:50:2 | SSA def(k) |

0 commit comments

Comments
 (0)