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:
metagn
2024-10-11 11:36:40 +03:00
committed by narimiran
parent ee4bf757ea
commit 090139eb6f
2 changed files with 25 additions and 1 deletions

View File

@@ -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:

View 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'