mirror of
https://github.com/github/codeql.git
synced 2026-07-31 23:42:59 +02:00
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.
This commit is contained in:
@@ -587,14 +587,6 @@ module GoCfg {
|
||||
n = any(Go::CompositeLit lit).getAnElement() and
|
||||
tag = "lit-init"
|
||||
or
|
||||
// Implicit literal element index
|
||||
exists(Go::CompositeLit lit |
|
||||
not lit instanceof Go::StructLit and
|
||||
n = lit.getAnElement() and
|
||||
not n instanceof Go::KeyValueExpr and
|
||||
tag = "lit-index"
|
||||
)
|
||||
or
|
||||
// Implicit field selection for promoted fields
|
||||
exists(int i, Go::Field implicitField |
|
||||
implicitFieldSelection(n, i, implicitField) and
|
||||
@@ -1480,17 +1472,12 @@ module GoCfg {
|
||||
not exists(lit.getElement(_)) and n2.isAfter(lit)
|
||||
)
|
||||
or
|
||||
// After element → optional lit-index → lit-init → next element or After
|
||||
// After element → lit-init → next element or After.
|
||||
// Positional array/slice elements have an implicit index that is
|
||||
// modelled on the `lit-init` instruction itself (see
|
||||
// `IR::InitLiteralElementInstruction`) rather than as a separate node.
|
||||
exists(int i |
|
||||
n1.isAfter(lit.getElement(i)) and
|
||||
(
|
||||
n2.isAdditional(lit.getElement(i), "lit-index")
|
||||
or
|
||||
not exists(PreControlFlowNode idx | idx.isAdditional(lit.getElement(i), "lit-index")) and
|
||||
n2.isAdditional(lit.getElement(i), "lit-init")
|
||||
)
|
||||
or
|
||||
n1.isAdditional(lit.getElement(i), "lit-index") and
|
||||
n2.isAdditional(lit.getElement(i), "lit-init")
|
||||
or
|
||||
n1.isAdditional(lit.getElement(i), "lit-init") and
|
||||
|
||||
@@ -159,8 +159,6 @@ module IR {
|
||||
or
|
||||
this instanceof InitLiteralComponentInstruction and result = "element init"
|
||||
or
|
||||
this instanceof ImplicitLiteralElementIndexInstruction and result = "element index"
|
||||
or
|
||||
this instanceof AssignInstruction and result = "assignment"
|
||||
or
|
||||
this instanceof EvalCompoundAssignRhsInstruction and
|
||||
@@ -578,7 +576,11 @@ module IR {
|
||||
Instruction getIndex() {
|
||||
result = evalExprInstruction(elt.(KeyValueExpr).getKey())
|
||||
or
|
||||
result.(ImplicitLiteralElementIndexInstruction).isAdditional(elt, "lit-index")
|
||||
// A positional array/slice element has an implicit index. Array/slice
|
||||
// content flow is index-insensitive, so rather than materialise a
|
||||
// separate index node the element-init instruction acts as its own
|
||||
// (opaque) index.
|
||||
not elt instanceof KeyValueExpr and result = this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -627,54 +629,6 @@ module IR {
|
||||
}
|
||||
}
|
||||
|
||||
private predicate noExplicitKeys(CompositeLit lit) {
|
||||
not lit.getAnElement() instanceof KeyValueExpr
|
||||
}
|
||||
|
||||
private int getElementIndex(CompositeLit lit, int i) {
|
||||
(
|
||||
lit.getType().getUnderlyingType() instanceof ArrayType or
|
||||
lit.getType().getUnderlyingType() instanceof SliceType
|
||||
) and
|
||||
exists(Expr elt | elt = lit.getElement(i) |
|
||||
noExplicitKeys(lit) and result = i
|
||||
or
|
||||
result = elt.(KeyValueExpr).getKey().getIntValue()
|
||||
or
|
||||
not elt instanceof KeyValueExpr and
|
||||
(
|
||||
i = 0 and result = 0
|
||||
or
|
||||
result = getElementIndex(lit, i - 1) + 1
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* An IR instruction computing the implicit index of an element in an array or slice literal.
|
||||
*/
|
||||
class ImplicitLiteralElementIndexInstruction extends Instruction {
|
||||
Expr elt;
|
||||
|
||||
ImplicitLiteralElementIndexInstruction() { this.isAdditional(elt, "lit-index") }
|
||||
|
||||
override Type getResultType() { result instanceof IntType }
|
||||
|
||||
override ControlFlow::Root getRoot() { result.isRootOf(elt) }
|
||||
|
||||
override int getIntValue() {
|
||||
exists(CompositeLit lit, int i | elt = lit.getElement(i) | result = getElementIndex(lit, i))
|
||||
}
|
||||
|
||||
override string getStringValue() { none() }
|
||||
|
||||
override string getExactValue() { result = this.getIntValue().toString() }
|
||||
|
||||
override predicate isPlatformIndependentConstant() { any() }
|
||||
|
||||
override predicate isConst() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction assigning to a variable or field.
|
||||
*/
|
||||
|
||||
@@ -969,9 +969,8 @@
|
||||
| exprs.go:16:17:16:23 | After struct3 | exprs.go:16:17:16:25 | selection of x |
|
||||
| exprs.go:16:17:16:23 | Before struct3 | exprs.go:16:17:16:23 | struct3 |
|
||||
| exprs.go:16:17:16:23 | struct3 | exprs.go:16:17:16:23 | After struct3 |
|
||||
| exprs.go:16:17:16:25 | After selection of x | exprs.go:16:17:16:25 | lit-index selection of x |
|
||||
| exprs.go:16:17:16:25 | After selection of x | exprs.go:16:17:16:25 | lit-init selection of x |
|
||||
| exprs.go:16:17:16:25 | Before selection of x | exprs.go:16:17:16:23 | Before struct3 |
|
||||
| exprs.go:16:17:16:25 | lit-index selection of x | exprs.go:16:17:16:25 | lit-init selection of x |
|
||||
| exprs.go:16:17:16:25 | lit-init selection of x | exprs.go:16:10:16:26 | After array literal |
|
||||
| exprs.go:16:17:16:25 | selection of x | exprs.go:16:17:16:25 | After selection of x |
|
||||
| exprs.go:17:2:17:40 | ... := ... | exprs.go:17:10:17:40 | Before array literal |
|
||||
@@ -983,9 +982,8 @@
|
||||
| exprs.go:17:19:17:25 | After struct3 | exprs.go:17:19:17:27 | selection of x |
|
||||
| exprs.go:17:19:17:25 | Before struct3 | exprs.go:17:19:17:25 | struct3 |
|
||||
| exprs.go:17:19:17:25 | struct3 | exprs.go:17:19:17:25 | After struct3 |
|
||||
| exprs.go:17:19:17:27 | After selection of x | exprs.go:17:19:17:27 | lit-index selection of x |
|
||||
| exprs.go:17:19:17:27 | After selection of x | exprs.go:17:19:17:27 | lit-init selection of x |
|
||||
| exprs.go:17:19:17:27 | Before selection of x | exprs.go:17:19:17:25 | Before struct3 |
|
||||
| exprs.go:17:19:17:27 | lit-index selection of x | exprs.go:17:19:17:27 | lit-init selection of x |
|
||||
| exprs.go:17:19:17:27 | lit-init selection of x | exprs.go:17:30:17:39 | Before key-value pair |
|
||||
| exprs.go:17:19:17:27 | selection of x | exprs.go:17:19:17:27 | After selection of x |
|
||||
| exprs.go:17:30:17:30 | 2 | exprs.go:17:30:17:30 | After 2 |
|
||||
@@ -1011,14 +1009,12 @@
|
||||
| exprs.go:18:9:18:22 | After slice literal | exprs.go:18:2:18:22 | assign:0 ... := ... |
|
||||
| exprs.go:18:9:18:22 | Before slice literal | exprs.go:18:9:18:22 | slice literal |
|
||||
| exprs.go:18:9:18:22 | slice literal | exprs.go:18:18:18:18 | Before s |
|
||||
| exprs.go:18:18:18:18 | After s | exprs.go:18:18:18:18 | lit-index s |
|
||||
| exprs.go:18:18:18:18 | After s | exprs.go:18:18:18:18 | lit-init s |
|
||||
| exprs.go:18:18:18:18 | Before s | exprs.go:18:18:18:18 | s |
|
||||
| exprs.go:18:18:18:18 | lit-index s | exprs.go:18:18:18:18 | lit-init s |
|
||||
| exprs.go:18:18:18:18 | lit-init s | exprs.go:18:21:18:21 | Before s |
|
||||
| exprs.go:18:18:18:18 | s | exprs.go:18:18:18:18 | After s |
|
||||
| exprs.go:18:21:18:21 | After s | exprs.go:18:21:18:21 | lit-index s |
|
||||
| exprs.go:18:21:18:21 | After s | exprs.go:18:21:18:21 | lit-init s |
|
||||
| exprs.go:18:21:18:21 | Before s | exprs.go:18:21:18:21 | s |
|
||||
| exprs.go:18:21:18:21 | lit-index s | exprs.go:18:21:18:21 | lit-init s |
|
||||
| exprs.go:18:21:18:21 | lit-init s | exprs.go:18:9:18:22 | After slice literal |
|
||||
| exprs.go:18:21:18:21 | s | exprs.go:18:21:18:21 | After s |
|
||||
| exprs.go:19:2:19:38 | ... := ... | exprs.go:19:8:19:38 | Before map literal |
|
||||
@@ -1373,19 +1369,16 @@
|
||||
| exprs.go:61:9:61:22 | Before slice literal | exprs.go:61:9:61:22 | slice literal |
|
||||
| exprs.go:61:9:61:22 | slice literal | exprs.go:61:15:61:15 | Before 1 |
|
||||
| exprs.go:61:15:61:15 | 1 | exprs.go:61:15:61:15 | After 1 |
|
||||
| exprs.go:61:15:61:15 | After 1 | exprs.go:61:15:61:15 | lit-index 1 |
|
||||
| exprs.go:61:15:61:15 | After 1 | exprs.go:61:15:61:15 | lit-init 1 |
|
||||
| exprs.go:61:15:61:15 | Before 1 | exprs.go:61:15:61:15 | 1 |
|
||||
| exprs.go:61:15:61:15 | lit-index 1 | exprs.go:61:15:61:15 | lit-init 1 |
|
||||
| exprs.go:61:15:61:15 | lit-init 1 | exprs.go:61:18:61:18 | Before 2 |
|
||||
| exprs.go:61:18:61:18 | 2 | exprs.go:61:18:61:18 | After 2 |
|
||||
| exprs.go:61:18:61:18 | After 2 | exprs.go:61:18:61:18 | lit-index 2 |
|
||||
| exprs.go:61:18:61:18 | After 2 | exprs.go:61:18:61:18 | lit-init 2 |
|
||||
| exprs.go:61:18:61:18 | Before 2 | exprs.go:61:18:61:18 | 2 |
|
||||
| exprs.go:61:18:61:18 | lit-index 2 | exprs.go:61:18:61:18 | lit-init 2 |
|
||||
| exprs.go:61:18:61:18 | lit-init 2 | exprs.go:61:21:61:21 | Before 3 |
|
||||
| exprs.go:61:21:61:21 | 3 | exprs.go:61:21:61:21 | After 3 |
|
||||
| exprs.go:61:21:61:21 | After 3 | exprs.go:61:21:61:21 | lit-index 3 |
|
||||
| exprs.go:61:21:61:21 | After 3 | exprs.go:61:21:61:21 | lit-init 3 |
|
||||
| exprs.go:61:21:61:21 | Before 3 | exprs.go:61:21:61:21 | 3 |
|
||||
| exprs.go:61:21:61:21 | lit-index 3 | exprs.go:61:21:61:21 | lit-init 3 |
|
||||
| exprs.go:61:21:61:21 | lit-init 3 | exprs.go:61:9:61:22 | After slice literal |
|
||||
| exprs.go:64:1:64:19 | After variable declaration | exprs.go:65:1:65:24 | variable declaration |
|
||||
| exprs.go:64:1:64:19 | variable declaration | exprs.go:64:5:64:19 | value declaration specifier |
|
||||
|
||||
Reference in New Issue
Block a user