mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +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.
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