diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2022-08-19 13:42:08 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-19 13:42:08 +0200 |
commit | b1fe1690c48fc3c24e3db2b2e2d12961f46f36f9 (patch) | |
tree | 85e597e1488e451775ed27defe667b73618ad171 | |
parent | 1c31de361d345c7cfc9ac2ca7a3040bdfa649d9a (diff) | |
download | Nim-b1fe1690c48fc3c24e3db2b2e2d12961f46f36f9.tar.gz |
fixes #20107 (#20246) [backport]
-rw-r--r-- | compiler/ccgexprs.nim | 14 | ||||
-rw-r--r-- | tests/ccgbugs/tderefblock.nim | 24 |
2 files changed, 38 insertions, 0 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 4c15101a9..1f16f458f 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -731,7 +731,21 @@ proc isCppRef(p: BProc; typ: PType): bool {.inline.} = skipTypes(typ, abstractInstOwned).kind in {tyVar} and tfVarIsPtr notin skipTypes(typ, abstractInstOwned).flags +proc derefBlock(p: BProc, e: PNode, d: var TLoc) = + # We transform (block: x)[] to (block: x[]) + let e0 = e[0] + var n = shallowCopy(e0) + for i in 0 ..< e0.len - 1: + n[i] = e0[i] + n[e0.len-1] = newTreeIT(nkHiddenDeref, e.info, e.typ, e0[e0.len-1]) + expr p, n, d + proc genDeref(p: BProc, e: PNode, d: var TLoc) = + if e.kind == nkHiddenDeref and e[0].kind in {nkBlockExpr, nkBlockStmt}: + # bug #20107. Watch out to not deref the pointer too late. + derefBlock(p, e, d) + return + let mt = mapType(p.config, e[0].typ, mapTypeChooser(e[0])) if mt in {ctArray, ctPtrToArray} and lfEnforceDeref notin d.flags: # XXX the amount of hacks for C's arrays is incredible, maybe we should diff --git a/tests/ccgbugs/tderefblock.nim b/tests/ccgbugs/tderefblock.nim new file mode 100644 index 000000000..55253da10 --- /dev/null +++ b/tests/ccgbugs/tderefblock.nim @@ -0,0 +1,24 @@ +discard """ + cmd: "nim c -d:release -d:danger $file" + output: "42" +""" + +# bug #20107 + +type Foo = object + a, b, c, d: uint64 + +proc c(i: uint64): Foo = + Foo(a: i, b: i, c: i, d: i) + +func x(f: Foo): lent Foo {.inline.} = + f + +proc m() = + let f = block: + let i = c(42) + x(i) + + echo $f.a + +m() |