fixes #26104; prevent compile-time-only typeof from being treated as a runtime alias

This commit is contained in:
ringabout
2026-08-13 22:08:24 +08:00
parent ebfd1c5090
commit b2bab45e23
2 changed files with 29 additions and 0 deletions

View File

@@ -25,6 +25,11 @@ type
pfStructural ## use structural prefix-chain detection and tree-walk
pfBidirectional ## also check reverse direction per field in nkObjConstr
proc isCompileTimeOnlyNode(n: PNode): bool {.inline.} =
## `typeof` and typedesc/static values describe types at compile time; they
## do not read the runtime location that alias analysis is protecting.
n.kind == nkTypeOfExpr or (n.typ != nil and n.typ.containsCompileTimeOnly)
func sameLocation(a, b: PNode): bool =
template sameConstIndex(a, b: PNode): bool =
a.kind in nkLiterals and b.kind in nkLiterals and a.intVal == b.intVal
@@ -157,6 +162,9 @@ proc isPartOf*(a, b: PNode; flags: set[PartFlag] = {}): TAnalysisResult =
##
## x[] ?<| y depending on type
## ```
if a.isCompileTimeOnlyNode or b.isCompileTimeOnlyNode:
return arNo
if a.kind == b.kind:
case a.kind
of nkSym:
@@ -271,6 +279,11 @@ proc isPartOf*(a, b: PNode; flags: set[PartFlag] = {}): TAnalysisResult =
of nkCallKinds:
result = arNo
for i in 1..<b.len:
# A call such as `fill(typeof(result.f))` has a compile-time-only
# argument. It must not make the object constructor look aliased with
# `result.f`; runtime arguments remain subject to the normal analysis.
if b[i].isCompileTimeOnlyNode:
continue
let res = isPartOf(a, b[i], flags)
if res != arNo:
result = res

16
tests/ccgbugs/t26104.nim Normal file
View File

@@ -0,0 +1,16 @@
discard """
action: compile
ccodeCheck: "@'f_.*((*Result).f)' .*"
"""
# bug #26104: a compile-time-only `typeof` argument was treated as a runtime
# alias of the result field, forcing an unnecessarily large temporary and copy.
type
B = array[131072, byte]
Y = object
f: B
proc fill(_: type B): B = discard
proc make(): Y = result.f = fill(typeof(result.f))
discard make()