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.
This commit is contained in:
metagn
2024-10-11 11:36:40 +03:00
committed by GitHub
parent 274762638f
commit 9c85f4fd07
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'