mirror of
https://github.com/github/codeql.git
synced 2026-07-12 23:15:40 +02:00
For an indexed array assignment `a[i] = v` (and its compound forms `a[i] op= v`),
the K1 and K2 frontends disagree on the source location of both the synthesised
array-access node (`...[...]`) and the assignment node (`...=...`/`...op=...`):
- K1 records the end offset at the left-hand side array access, e.g.
`a1[0] = a1[0]` gets `12:3:12:7` (just `a1[0]`).
- K2 spans through the assigned value, e.g. `12:3:12:15` (the whole `a1[0] = a1[0]`).
Decision: adopt the K2 span. An assignment expression should cover its whole
source range (left-hand side through the right-hand value), consistent with how
ordinary (non-indexed) assignments are already located and with the Java
extractor's array-store locations. This makes location-based queries (and any
`...=...`/`...[...]` overlap reasoning) behave the same regardless of frontend.
Implementation: the set operation is desugared to an array `set` call. Two code
paths build these nodes, and both used the raw call/block end offset:
- simple `a[i] = v` -> the `Array.set` IrCall branch in `extractCall`
- compound `a[i] op= v` -> `tryExtractArrayUpdate`
Each now widens the end offset to the assigned value's end via a small offset-based
`correctedEndOffset(rawEnd, valueEnd)` helper (extracted from the existing
`correctedEndOffset(IrExpression)` so the two share one rule). The widening only
fires when the value's end lies past the raw end, so it is a no-op under K2 (where
the raw end already spans the value) and ignores undefined/synthetic offsets. A new
`TrapWriter.getLocation(e, endOffset)` overload preserves the existing IrCall
start-offset adjustment while overriding just the end.
Tradeoff: the change is deliberately scoped to the two array-assignment paths
rather than globally rewriting how set-call locations are derived, to avoid
perturbing unrelated expressions. Only the `test-kotlin1` array expected files
change; `test-kotlin2` is unaffected, and the two suites' `arrayAccesses` and
`assignExprs` expected files are now byte-identical. All 3333 tests pass in both
K1 and K2 modes (with database-consistency checks).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>