diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index ca03634455..941c0cc5cc 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -3118,16 +3118,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 8749d182a8..c1d9a59908 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -1519,15 +1519,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 630c04965c..6e235fe430 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -497,7 +497,17 @@ proc transformAddrDeref(c: PTransf, n: PNode, kinds: TNodeKinds, isAddr = false) elif n.typ.skipTypes(abstractInst).kind in {tyVar}: result.typ = toVar(result.typ, n.typ.skipTypes(abstractInst).kind, c.idgen) else: - if n[0].kind in kinds: + if n[0].kind in kinds and + not (n[0][0].kind == nkSym and n[0][0].sym.kind == skForVar and + n[0][0].typ.skipTypes(abstractVar).kind == tyTuple + ) 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) 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 result = n[0][0] if n.typ.skipTypes(abstractVar).kind != tyOpenArray: @@ -1035,9 +1045,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 cfda1da7c0..457af0f28c 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())[])