Merge branch 'devel' into pr_dhbcvidf

This commit is contained in:
ringabout
2026-06-05 13:05:15 +08:00
committed by GitHub
3 changed files with 62 additions and 0 deletions

View File

@@ -185,6 +185,9 @@ proc root(v: var Partitions; start: int): int =
proc potentialMutation(v: var Partitions; s: PSym; level: int; info: TLineInfo) =
let id = variableId(v, s)
if id >= 0:
# mutated here => alive here: keep aliveEnd in sync so dangerousMutation catches
# mutations recorded after the var's last use (e.g. via a call arg). See #25595.
v.s[id].aliveEnd = max(v.s[id].aliveEnd, v.abstractTime)
let r = root(v, id)
let flags = if s.kind == skParam:
if isConstParam(s):

43
tests/arc/t25595.nim Normal file
View File

@@ -0,0 +1,43 @@
discard """
matrix: "--mm:orc; --mm:arc; --mm:refc"
"""
# bug #25595: cursor inference must not borrow a case object whose source can be
# mutated through the cursor's own ref across a call. `let c = h.w` was inferred as a
# non-owning cursor; `clear(c.r)` overwrites `h.w` via the cursor's back-reference,
# freeing the ref while the borrow still uses it -> use-after-free. Detected here
# deterministically: the element's destructor must not run during the call.
var destroyed = false
type
O = ref object
value: int
home: H
W = object
case k: bool
of true: r: O
of false: discard
H = ref object
w: W
proc `=destroy`(o: var typeof(O()[])) =
destroyed = true
proc clear(o: O): int =
o.home.w = W()
doAssert not destroyed, "use-after-free: element destroyed during the call"
result = o.value
proc go(h: H): int =
let c = h.w
result = clear(c.r)
proc main =
let h = H()
let o = O(value: 42)
o.home = h
h.w = W(k: true, r: o)
doAssert go(h) == 42
main()

16
tests/vm/t25849.nim Normal file
View File

@@ -0,0 +1,16 @@
discard """
targets: "c cpp js"
"""
import std/os
from std/sequtils import toSeq
iterator items(a: array[3, string]): lent string {.inline.} =
for i in 0..2:
yield a[i]
static:
const key = "NIM_TESTS_TOSENV_KEY"
for val in items(["a", "b", "c"]):
putEnv(key, val)
doAssert (key, val) in toSeq(envPairs())