mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-14 11:04:34 +00:00
fixes #26104; prevent compile-time-only typeof from being treated as a runtime alias
This commit is contained in:
@@ -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
16
tests/ccgbugs/t26104.nim
Normal 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()
|
||||
Reference in New Issue
Block a user