Skip to content

Commit f07ab45

Browse files
committed
Fold implicit literal element index into the lit-init node
A positional element of an array or slice literal (e.g. the elements of []T{a, b}) previously created a 'lit-index' node holding its implicit index constant (0, 1, ...), in addition to the 'lit-init' write node. Array and slice content flow is index-insensitive (the store step ignores the element index), map literals always use explicit keys, and literal bases are not tracked by VariableWithFields, so the implicit index value is never actually consumed. Drop the 'lit-index' node and let the lit-init instruction act as its own opaque index. All 100 data-flow library tests pass unchanged, confirming no content-flow loss.
1 parent 57951e2 commit f07ab45

3 files changed

Lines changed: 16 additions & 82 deletions

File tree

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

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -587,14 +587,6 @@ module GoCfg {
587587
n = any(Go::CompositeLit lit).getAnElement() and
588588
tag = "lit-init"
589589
or
590-
// Implicit literal element index
591-
exists(Go::CompositeLit lit |
592-
not lit instanceof Go::StructLit and
593-
n = lit.getAnElement() and
594-
not n instanceof Go::KeyValueExpr and
595-
tag = "lit-index"
596-
)
597-
or
598590
// Implicit field selection for promoted fields
599591
exists(int i, Go::Field implicitField |
600592
implicitFieldSelection(n, i, implicitField) and
@@ -1480,17 +1472,12 @@ module GoCfg {
14801472
not exists(lit.getElement(_)) and n2.isAfter(lit)
14811473
)
14821474
or
1483-
// After element → optional lit-index → lit-init → next element or After
1475+
// After element → lit-init → next element or After.
1476+
// Positional array/slice elements have an implicit index that is
1477+
// modelled on the `lit-init` instruction itself (see
1478+
// `IR::InitLiteralElementInstruction`) rather than as a separate node.
14841479
exists(int i |
14851480
n1.isAfter(lit.getElement(i)) and
1486-
(
1487-
n2.isAdditional(lit.getElement(i), "lit-index")
1488-
or
1489-
not exists(PreControlFlowNode idx | idx.isAdditional(lit.getElement(i), "lit-index")) and
1490-
n2.isAdditional(lit.getElement(i), "lit-init")
1491-
)
1492-
or
1493-
n1.isAdditional(lit.getElement(i), "lit-index") and
14941481
n2.isAdditional(lit.getElement(i), "lit-init")
14951482
or
14961483
n1.isAdditional(lit.getElement(i), "lit-init") and

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

Lines changed: 5 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,6 @@ module IR {
159159
or
160160
this instanceof InitLiteralComponentInstruction and result = "element init"
161161
or
162-
this instanceof ImplicitLiteralElementIndexInstruction and result = "element index"
163-
or
164162
this instanceof AssignInstruction and result = "assignment"
165163
or
166164
this instanceof EvalCompoundAssignRhsInstruction and
@@ -578,7 +576,11 @@ module IR {
578576
Instruction getIndex() {
579577
result = evalExprInstruction(elt.(KeyValueExpr).getKey())
580578
or
581-
result.(ImplicitLiteralElementIndexInstruction).isAdditional(elt, "lit-index")
579+
// A positional array/slice element has an implicit index. Array/slice
580+
// content flow is index-insensitive, so rather than materialise a
581+
// separate index node the element-init instruction acts as its own
582+
// (opaque) index.
583+
not elt instanceof KeyValueExpr and result = this
582584
}
583585
}
584586

@@ -627,54 +629,6 @@ module IR {
627629
}
628630
}
629631

630-
private predicate noExplicitKeys(CompositeLit lit) {
631-
not lit.getAnElement() instanceof KeyValueExpr
632-
}
633-
634-
private int getElementIndex(CompositeLit lit, int i) {
635-
(
636-
lit.getType().getUnderlyingType() instanceof ArrayType or
637-
lit.getType().getUnderlyingType() instanceof SliceType
638-
) and
639-
exists(Expr elt | elt = lit.getElement(i) |
640-
noExplicitKeys(lit) and result = i
641-
or
642-
result = elt.(KeyValueExpr).getKey().getIntValue()
643-
or
644-
not elt instanceof KeyValueExpr and
645-
(
646-
i = 0 and result = 0
647-
or
648-
result = getElementIndex(lit, i - 1) + 1
649-
)
650-
)
651-
}
652-
653-
/**
654-
* An IR instruction computing the implicit index of an element in an array or slice literal.
655-
*/
656-
class ImplicitLiteralElementIndexInstruction extends Instruction {
657-
Expr elt;
658-
659-
ImplicitLiteralElementIndexInstruction() { this.isAdditional(elt, "lit-index") }
660-
661-
override Type getResultType() { result instanceof IntType }
662-
663-
override ControlFlow::Root getRoot() { result.isRootOf(elt) }
664-
665-
override int getIntValue() {
666-
exists(CompositeLit lit, int i | elt = lit.getElement(i) | result = getElementIndex(lit, i))
667-
}
668-
669-
override string getStringValue() { none() }
670-
671-
override string getExactValue() { result = this.getIntValue().toString() }
672-
673-
override predicate isPlatformIndependentConstant() { any() }
674-
675-
override predicate isConst() { any() }
676-
}
677-
678632
/**
679633
* An instruction assigning to a variable or field.
680634
*/

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

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -969,9 +969,8 @@
969969
| exprs.go:16:17:16:23 | After struct3 | exprs.go:16:17:16:25 | selection of x |
970970
| exprs.go:16:17:16:23 | Before struct3 | exprs.go:16:17:16:23 | struct3 |
971971
| exprs.go:16:17:16:23 | struct3 | exprs.go:16:17:16:23 | After struct3 |
972-
| exprs.go:16:17:16:25 | After selection of x | exprs.go:16:17:16:25 | lit-index selection of x |
972+
| exprs.go:16:17:16:25 | After selection of x | exprs.go:16:17:16:25 | lit-init selection of x |
973973
| exprs.go:16:17:16:25 | Before selection of x | exprs.go:16:17:16:23 | Before struct3 |
974-
| exprs.go:16:17:16:25 | lit-index selection of x | exprs.go:16:17:16:25 | lit-init selection of x |
975974
| exprs.go:16:17:16:25 | lit-init selection of x | exprs.go:16:10:16:26 | After array literal |
976975
| exprs.go:16:17:16:25 | selection of x | exprs.go:16:17:16:25 | After selection of x |
977976
| exprs.go:17:2:17:40 | ... := ... | exprs.go:17:10:17:40 | Before array literal |
@@ -983,9 +982,8 @@
983982
| exprs.go:17:19:17:25 | After struct3 | exprs.go:17:19:17:27 | selection of x |
984983
| exprs.go:17:19:17:25 | Before struct3 | exprs.go:17:19:17:25 | struct3 |
985984
| exprs.go:17:19:17:25 | struct3 | exprs.go:17:19:17:25 | After struct3 |
986-
| exprs.go:17:19:17:27 | After selection of x | exprs.go:17:19:17:27 | lit-index selection of x |
985+
| exprs.go:17:19:17:27 | After selection of x | exprs.go:17:19:17:27 | lit-init selection of x |
987986
| exprs.go:17:19:17:27 | Before selection of x | exprs.go:17:19:17:25 | Before struct3 |
988-
| exprs.go:17:19:17:27 | lit-index selection of x | exprs.go:17:19:17:27 | lit-init selection of x |
989987
| exprs.go:17:19:17:27 | lit-init selection of x | exprs.go:17:30:17:39 | Before key-value pair |
990988
| exprs.go:17:19:17:27 | selection of x | exprs.go:17:19:17:27 | After selection of x |
991989
| exprs.go:17:30:17:30 | 2 | exprs.go:17:30:17:30 | After 2 |
@@ -1011,14 +1009,12 @@
10111009
| exprs.go:18:9:18:22 | After slice literal | exprs.go:18:2:18:22 | assign:0 ... := ... |
10121010
| exprs.go:18:9:18:22 | Before slice literal | exprs.go:18:9:18:22 | slice literal |
10131011
| exprs.go:18:9:18:22 | slice literal | exprs.go:18:18:18:18 | Before s |
1014-
| exprs.go:18:18:18:18 | After s | exprs.go:18:18:18:18 | lit-index s |
1012+
| exprs.go:18:18:18:18 | After s | exprs.go:18:18:18:18 | lit-init s |
10151013
| exprs.go:18:18:18:18 | Before s | exprs.go:18:18:18:18 | s |
1016-
| exprs.go:18:18:18:18 | lit-index s | exprs.go:18:18:18:18 | lit-init s |
10171014
| exprs.go:18:18:18:18 | lit-init s | exprs.go:18:21:18:21 | Before s |
10181015
| exprs.go:18:18:18:18 | s | exprs.go:18:18:18:18 | After s |
1019-
| exprs.go:18:21:18:21 | After s | exprs.go:18:21:18:21 | lit-index s |
1016+
| exprs.go:18:21:18:21 | After s | exprs.go:18:21:18:21 | lit-init s |
10201017
| exprs.go:18:21:18:21 | Before s | exprs.go:18:21:18:21 | s |
1021-
| exprs.go:18:21:18:21 | lit-index s | exprs.go:18:21:18:21 | lit-init s |
10221018
| exprs.go:18:21:18:21 | lit-init s | exprs.go:18:9:18:22 | After slice literal |
10231019
| exprs.go:18:21:18:21 | s | exprs.go:18:21:18:21 | After s |
10241020
| exprs.go:19:2:19:38 | ... := ... | exprs.go:19:8:19:38 | Before map literal |
@@ -1373,19 +1369,16 @@
13731369
| exprs.go:61:9:61:22 | Before slice literal | exprs.go:61:9:61:22 | slice literal |
13741370
| exprs.go:61:9:61:22 | slice literal | exprs.go:61:15:61:15 | Before 1 |
13751371
| exprs.go:61:15:61:15 | 1 | exprs.go:61:15:61:15 | After 1 |
1376-
| exprs.go:61:15:61:15 | After 1 | exprs.go:61:15:61:15 | lit-index 1 |
1372+
| exprs.go:61:15:61:15 | After 1 | exprs.go:61:15:61:15 | lit-init 1 |
13771373
| exprs.go:61:15:61:15 | Before 1 | exprs.go:61:15:61:15 | 1 |
1378-
| exprs.go:61:15:61:15 | lit-index 1 | exprs.go:61:15:61:15 | lit-init 1 |
13791374
| exprs.go:61:15:61:15 | lit-init 1 | exprs.go:61:18:61:18 | Before 2 |
13801375
| exprs.go:61:18:61:18 | 2 | exprs.go:61:18:61:18 | After 2 |
1381-
| exprs.go:61:18:61:18 | After 2 | exprs.go:61:18:61:18 | lit-index 2 |
1376+
| exprs.go:61:18:61:18 | After 2 | exprs.go:61:18:61:18 | lit-init 2 |
13821377
| exprs.go:61:18:61:18 | Before 2 | exprs.go:61:18:61:18 | 2 |
1383-
| exprs.go:61:18:61:18 | lit-index 2 | exprs.go:61:18:61:18 | lit-init 2 |
13841378
| exprs.go:61:18:61:18 | lit-init 2 | exprs.go:61:21:61:21 | Before 3 |
13851379
| exprs.go:61:21:61:21 | 3 | exprs.go:61:21:61:21 | After 3 |
1386-
| exprs.go:61:21:61:21 | After 3 | exprs.go:61:21:61:21 | lit-index 3 |
1380+
| exprs.go:61:21:61:21 | After 3 | exprs.go:61:21:61:21 | lit-init 3 |
13871381
| exprs.go:61:21:61:21 | Before 3 | exprs.go:61:21:61:21 | 3 |
1388-
| exprs.go:61:21:61:21 | lit-index 3 | exprs.go:61:21:61:21 | lit-init 3 |
13891382
| exprs.go:61:21:61:21 | lit-init 3 | exprs.go:61:9:61:22 | After slice literal |
13901383
| exprs.go:64:1:64:19 | After variable declaration | exprs.go:65:1:65:24 | variable declaration |
13911384
| exprs.go:64:1:64:19 | variable declaration | exprs.go:64:5:64:19 | value declaration specifier |

0 commit comments

Comments
 (0)