mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-04 20:17:42 +00:00
fix deref/addr pair deleting assignment location in C++ (#24280)
fixes #24274
The code in the `if` branch replaces the current destination `d` with a
new one. But the location `d` can be an assignment location, in which
case the provided expression isn't generated. To fix this, don't trigger
this code for when the location already exists. An alternative would be
to call `putIntoDest` in this case as is done below.
(cherry picked from commit 9c85f4fd07)
This commit is contained in:
@@ -758,7 +758,10 @@ proc genDeref(p: BProc, e: PNode, d: var TLoc) =
|
||||
if typ.kind in {tyUserTypeClass, tyUserTypeClassInst} and typ.isResolvedUserTypeClass:
|
||||
typ = typ.last
|
||||
typ = typ.skipTypes(abstractInstOwned)
|
||||
if typ.kind in {tyVar} and tfVarIsPtr notin typ.flags and p.module.compileToCpp and e[0].kind == nkHiddenAddr:
|
||||
if typ.kind in {tyVar} and tfVarIsPtr notin typ.flags and
|
||||
p.module.compileToCpp and e[0].kind == nkHiddenAddr and
|
||||
# don't override existing location:
|
||||
d.k == locNone:
|
||||
d = initLocExprSingleUse(p, e[0][0])
|
||||
return
|
||||
else:
|
||||
|
||||
21
tests/ccgbugs/tvararrayiter.nim
Normal file
21
tests/ccgbugs/tvararrayiter.nim
Normal file
@@ -0,0 +1,21 @@
|
||||
discard """
|
||||
targets: "c cpp"
|
||||
"""
|
||||
|
||||
block: # issue #24274
|
||||
iterator foo[T](x: var T): var T =
|
||||
yield x
|
||||
|
||||
var x: array[3, char]
|
||||
for a in foo(x):
|
||||
let b = a
|
||||
|
||||
var y: array[3, char] = ['a', 'b', 'c']
|
||||
for a in foo(y):
|
||||
let b = a
|
||||
doAssert a[0] == 'a'
|
||||
doAssert a[1] == 'b'
|
||||
doAssert a[2] == 'c'
|
||||
doAssert b[0] == 'a'
|
||||
doAssert b[1] == 'b'
|
||||
doAssert b[2] == 'c'
|
||||
Reference in New Issue
Block a user