diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2023-06-16 20:59:59 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-16 20:59:59 +0200 |
commit | e8d0f1c3aedd8290cc972e3d06f642e88dbe783e (patch) | |
tree | fff0c7880eb78749439c3c57fae764978405531d /compiler | |
parent | 0de9e6bbf33bd013e39025f0ee81fc86956e70cf (diff) | |
download | Nim-e8d0f1c3aedd8290cc972e3d06f642e88dbe783e.tar.gz |
fixes #16331; aliasing of tuple construction within a single assignme… (#22113)
* fixes #16331; aliasing of tuple construction within a single assignment, great coding style * added test case
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ccgexprs.nim | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 0567fbdf9..978ca8db8 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -2679,15 +2679,30 @@ proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) = if not handleConstExpr(p, n, d): let t = n.typ discard getTypeDesc(p.module, t) # so that any fields are initialized - if d.k == locNone: getTemp(p, t, d) + + var tmp: TLoc + # bug #16331 + let doesAlias = lhsDoesAlias(d.lode, n) + let dest = if doesAlias: addr(tmp) else: addr(d) + if doesAlias: + getTemp(p, n.typ, tmp) + elif d.k == locNone: + getTemp(p, n.typ, d) + for i in 0..<n.len: var it = n[i] if it.kind == nkExprColonExpr: it = it[1] - initLoc(rec, locExpr, it, d.storage) - rec.r = "$1.Field$2" % [rdLoc(d), rope(i)] + initLoc(rec, locExpr, it, dest[].storage) + rec.r = "$1.Field$2" % [rdLoc(dest[]), rope(i)] rec.flags.incl(lfEnforceDeref) expr(p, it, rec) + if doesAlias: + if d.k == locNone: + d = tmp + else: + genAssignment(p, d, tmp, {}) + proc isConstClosure(n: PNode): bool {.inline.} = result = n[0].kind == nkSym and isRoutine(n[0].sym) and n[1].kind == nkNilLit |