From aa90d00caf1277decb33575397e64d544d0b6eb4 Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Sat, 26 Oct 2024 04:36:19 +0800 Subject: [PATCH] fixes #18081; fixes #18079; fixes #18080; nested ref/deref'd types (#24335) fixes #18081; fixes https://github.com/nim-lang/Nim/issues/18080 fixes #18079 reverts https://github.com/nim-lang/Nim/pull/20738 It is probably more reasonable to use the type node from `nkObjConstr` since it is barely changed unlike the external type, which is susceptible to code transformation e.g. `addr(deref objconstr)`. --- compiler/ccgexprs.nim | 11 +---------- compiler/jsgen.nim | 9 +-------- compiler/transf.nim | 8 ++++---- tests/ccgbugs/t13062.nim | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index bb57c2dc273a..36fb8ae19531 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -3144,16 +3144,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = of nkObjConstr: genObjConstr(p, n, d) of nkCast: genCast(p, n, d) of nkHiddenStdConv, nkHiddenSubConv, nkConv: genConv(p, n, d) - of nkHiddenAddr: - if n[0].kind == nkDerefExpr: - # addr ( deref ( x )) --> x - var x = n[0][0] - if n.typ.skipTypes(abstractVar).kind != tyOpenArray: - x.typ() = n.typ - expr(p, x, d) - return - genAddr(p, n, d) - of nkAddr: genAddr(p, n, d) + of nkAddr, nkHiddenAddr: genAddr(p, n, d) of nkBracketExpr: genBracketExpr(p, n, d) of nkDerefExpr, nkHiddenDeref: genDeref(p, n, d) of nkDotExpr: genRecordField(p, n, d) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 21781efde06a..442d731a3e3a 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -1585,15 +1585,8 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) = else: internalError(p.config, n[0].info, "expr(nkBracketExpr, " & $kindOfIndexedExpr & ')') of nkObjDownConv: gen(p, n[0], r) - of nkHiddenDeref: + of nkHiddenDeref, nkDerefExpr: gen(p, n[0], r) - of nkDerefExpr: - var x = n[0] - if n.kind == nkHiddenAddr: - x = n[0][0] - if n.typ.skipTypes(abstractVar).kind != tyOpenArray: - x.typ() = n.typ - gen(p, x, r) of nkHiddenAddr: gen(p, n[0], r) of nkConv: diff --git a/compiler/transf.nim b/compiler/transf.nim index bd1a9cc4ca1f..615bff31ee6b 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -507,7 +507,9 @@ proc transformAddrDeref(c: PTransf, n: PNode, kinds: TNodeKinds, isAddr = false) ) and not (n[0][0].kind == nkSym and n[0][0].sym.kind == skParam and n.typ.kind == tyVar and n.typ.skipTypes(abstractVar).kind == tyOpenArray and - n[0][0].typ.skipTypes(abstractVar).kind == tyString) + n[0][0].typ.skipTypes(abstractVar).kind == tyString) and + not (isAddr and n.typ.kind == tyVar and n[0][0].typ.kind == tyRef and + n[0][0].kind == nkObjConstr) : # elimination is harmful to `for tuple unpack` because of newTupleAccess # it is also harmful to openArrayLoc (var openArray) for strings # addr ( deref ( x )) --> x @@ -1075,9 +1077,7 @@ proc transform(c: PTransf, n: PNode, noConstFold = false): PNode = of nkBreakStmt: result = transformBreak(c, n) of nkCallKinds: result = transformCall(c, n) - of nkHiddenAddr: - result = transformAddrDeref(c, n, {nkHiddenDeref}, isAddr = true) - of nkAddr: + of nkAddr, nkHiddenAddr: result = transformAddrDeref(c, n, {nkDerefExpr, nkHiddenDeref}, isAddr = true) of nkDerefExpr: result = transformAddrDeref(c, n, {nkAddr, nkHiddenAddr}) diff --git a/tests/ccgbugs/t13062.nim b/tests/ccgbugs/t13062.nim index cfda1da7c07e..457af0f28c49 100644 --- a/tests/ccgbugs/t13062.nim +++ b/tests/ccgbugs/t13062.nim @@ -31,3 +31,39 @@ elif defined(gcRefc): doAssert x.repr == "[p = nil]" else: # fixme # bug #20081 doAssert x.repr == "Pledge(p: nil)" + +block: + block: # bug #18081 + type + Foo = object + discard + + Bar = object + x: Foo + + proc baz(state: var Bar) = + state.x = Foo() + + baz((ref Bar)(x: (new Foo)[])[]) + + block: # bug #18079 + type + Foo = object + discard + + Bar = object + x: Foo + + proc baz(state: var Bar) = discard + baz((ref Bar)(x: (new Foo)[])[]) + + block: # bug #18080 + type + Foo = object + discard + + Bar = object + x: Foo + + proc baz(state: var Bar) = discard + baz((ref Bar)(x: Foo())[])