From 973065b279d2ae5b3954c25348c7dc4a02335f2b Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Thu, 3 Sep 2026 19:46:44 +0800 Subject: [PATCH] =?UTF-8?q?fixes=20#26158;=20incRef:=20interiorPtrTracebac?= =?UTF-8?q?k/SIGSEGV=20with=20closure=20itera=E2=80=A6=20(#26162)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …tor iterating over tuples in refc fixes #26158 --- compiler/ccgexprs.nim | 10 +++++++++- tests/iter/tclosureiters.nim | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index eb3ee4bfb7..2e49cc8c33 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -424,7 +424,15 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = simpleAsgn(p.s(cpsStmts), dest, src) of tyArray: if containsGarbageCollectedRef(dest.t) and p.config.selectedGC notin {gcArc, gcAtomicArc, gcOrc, gcYrc, gcHooks}: - genGenericAsgn(p, dest, src, flags) + # Static array literals may contain GC-managed values (for example, + # strings). They must be copied deeply so that the destination does not + # attempt to adjust the reference count of the static literal's + # interior pointers. This mirrors the handling for tuples and objects + # above, where static sources force a real copy. + let newflags = + if src.storage == OnStatic: flags + {needToCopy} + else: flags + genGenericAsgn(p, dest, src, newflags) else: let rd = rdLoc(dest) let rs = rdLoc(src) diff --git a/tests/iter/tclosureiters.nim b/tests/iter/tclosureiters.nim index 4a26398523..7ea9d8c4cd 100644 --- a/tests/iter/tclosureiters.nim +++ b/tests/iter/tclosureiters.nim @@ -174,3 +174,19 @@ iterator pairs(): (int, int) {.closure.} = for pair in pairs(): echo pair + +# issue #26158: static array literals containing strings must be copied safely +# when a closure iterator stores them in its environment. +iterator fromStatic(): int {.closure.} = + for _ in static([(" ",)]): + break + +for _ in fromStatic(): + break + +iterator fromLiteral(): int {.closure.} = + for _ in [(" ",)]: + break + +for _ in fromLiteral(): + break