fixes #22669 constructor pragma doesnt init Nim default fields (#22670)

fixes #22669 constructor pragma doesnt init Nim default fields

---------

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
Juan M Gómez
2023-09-10 11:45:36 +01:00
committed by GitHub
parent cd24195d44
commit 8032f252b2
4 changed files with 66 additions and 20 deletions

View File

@@ -1494,8 +1494,27 @@ proc handleConstExpr(p: BProc, n: PNode, d: var TLoc): bool =
else:
result = false
proc genFieldObjConstr(p: BProc; ty: PType; useTemp, isRef: bool; nField, val, check: PNode; d: var TLoc; r: Rope; info: TLineInfo) =
var tmp2: TLoc = default(TLoc)
tmp2.r = r
let field = lookupFieldAgain(p, ty, nField.sym, tmp2.r)
if field.loc.r == "": fillObjectFields(p.module, ty)
if field.loc.r == "": internalError(p.config, info, "genFieldObjConstr")
if check != nil and optFieldCheck in p.options:
genFieldCheck(p, check, r, field)
tmp2.r.add(".")
tmp2.r.add(field.loc.r)
if useTemp:
tmp2.k = locTemp
tmp2.storage = if isRef: OnHeap else: OnStack
else:
tmp2.k = d.k
tmp2.storage = if isRef: OnHeap else: d.storage
tmp2.lode = val
expr(p, val, tmp2)
proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
#echo renderTree e, " ", e.isDeepConstExpr
# inheritance in C++ does not allow struct initialization so
# we skip this step here:
if not p.module.compileToCpp and optSeqDestructors notin p.config.globalOptions:
@@ -1534,24 +1553,11 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
discard getTypeDesc(p.module, t)
let ty = getUniqueType(t)
for i in 1..<e.len:
let it = e[i]
var tmp2: TLoc = default(TLoc)
tmp2.r = r
let field = lookupFieldAgain(p, ty, it[0].sym, tmp2.r)
if field.loc.r == "": fillObjectFields(p.module, ty)
if field.loc.r == "": internalError(p.config, e.info, "genObjConstr")
if it.len == 3 and optFieldCheck in p.options:
genFieldCheck(p, it[2], r, field)
tmp2.r.add(".")
tmp2.r.add(field.loc.r)
if useTemp:
tmp2.k = locTemp
tmp2.storage = if isRef: OnHeap else: OnStack
else:
tmp2.k = d.k
tmp2.storage = if isRef: OnHeap else: d.storage
tmp2.lode = it[1]
expr(p, it[1], tmp2)
var check: PNode = nil
if e[i].len == 3 and optFieldCheck in p.options:
check = e[i][2]
genFieldObjConstr(p, ty, useTemp, isRef, e[i][0], e[i][1], check, d, r, e.info)
if useTemp:
if d.k == locNone:
d = tmp

View File

@@ -1171,6 +1171,11 @@ proc genProcAux*(m: BModule, prc: PSym) =
returnStmt = ropecg(p.module, "\treturn $1;$n", [rdLoc(res.loc)])
elif sfConstructor in prc.flags:
fillLoc(resNode.sym.loc, locParam, resNode, "this", OnHeap)
let ty = resNode.sym.typ[0] #generate nim's ctor
for i in 1..<resNode.sym.ast.len:
let field = resNode.sym.ast[i]
genFieldObjConstr(p, ty, useTemp = false, isRef = false,
field[0], field[1], check = nil, resNode.sym.loc, "(*this)", tmpInfo)
else:
fillResult(p.config, resNode, prc.typ)
assignParam(p, res, prc.typ[0])

View File

@@ -1711,6 +1711,8 @@ proc addThis(c: PContext, n: PNode, t: PType, owner: TSymKind) =
c.p.resultSym = s
n.add newSymNode(c.p.resultSym)
addParamOrResult(c, c.p.resultSym, owner)
#resolves nim's obj ctor inside cpp ctors see #22669
s.ast = c.semExpr(c, newTree(nkCall, t[0].sym.ast[0]))
proc addResult(c: PContext, n: PNode, t: PType, owner: TSymKind) =
template genResSym(s) =

View File

@@ -7,6 +7,15 @@ discard """
123
0
123
___
0
777
10
123
0
777
10
123
'''
"""
@@ -73,4 +82,28 @@ proc main =
n.x = 123
echo n.x
main()
main()
#bug:
echo "___"
type
NimClassWithDefault = object
x: int
y = 777
case kind: bool = true
of true:
z: int = 10
else: discard
proc makeNimClassWithDefault(): NimClassWithDefault {.constructor.} =
discard
proc init =
for i in 0 .. 1:
var n = makeNimClassWithDefault()
echo n.x
echo n.y
echo n.z
n.x = 123
echo n.x
init()