From 1bbbb2f46bd0b3f010f03cb5143cb8c0969e8c32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20M=20G=C3=B3mez?= Date: Fri, 8 Sep 2023 09:46:40 +0100 Subject: [PATCH] fixes #22662 Procs with constructor pragma doesn't initialize object's fields (#22665) fixes #22662 Procs with constructor pragma doesn't initialize object's fields --------- Co-authored-by: Andreas Rumpf (cherry picked from commit d45270bdf721e195a9dae344f9a3285d066c3932) --- compiler/ccgtypes.nim | 9 ++++++++- tests/cpp/tconstructor.nim | 23 ++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index b40f8a5dac..2613df14ad 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -660,6 +660,13 @@ proc mangleRecFieldName(m: BModule; field: PSym): Rope = result = rope(mangleField(m, field.name)) if result == "": internalError(m.config, field.info, "mangleRecFieldName") +proc hasCppCtor(m: BModule; typ: PType): bool = + result = false + if m.compileToCpp and typ != nil and typ.itemId in m.g.graph.memberProcsPerType: + for prc in m.g.graph.memberProcsPerType[typ.itemId]: + if sfConstructor in prc.flags: + return true + proc genRecordFieldsAux(m: BModule; n: PNode, rectype: PType, check: var IntSet; result: var Rope; unionPrefix = "") = @@ -724,7 +731,7 @@ proc genRecordFieldsAux(m: BModule; n: PNode, else: # don't use fieldType here because we need the # tyGenericInst for C++ template support - if fieldType.isOrHasImportedCppType(): + if fieldType.isOrHasImportedCppType() or hasCppCtor(m, field.owner.typ): result.addf("\t$1$3 $2{};$n", [getTypeDescAux(m, field.loc.t, check, dkField), sname, noAlias]) else: result.addf("\t$1$3 $2;$n", [getTypeDescAux(m, field.loc.t, check, dkField), sname, noAlias]) diff --git a/tests/cpp/tconstructor.nim b/tests/cpp/tconstructor.nim index d4d6a7ccfa..b691626614 100644 --- a/tests/cpp/tconstructor.nim +++ b/tests/cpp/tconstructor.nim @@ -3,6 +3,10 @@ discard """ cmd: "nim cpp $file" output: ''' 1 +0 +123 +0 +123 ''' """ @@ -52,4 +56,21 @@ proc makeCppClass(): NimClass {. constructor: "NimClass() : CppClass(0, 0) ".} = this.x = 1 let nimClass = makeNimClass(1) -var nimClassDef {.used.}: NimClass #since we explictly defined the default constructor we can declare the obj \ No newline at end of file +var nimClassDef {.used.}: NimClass #since we explictly defined the default constructor we can declare the obj + +#bug: 22662 +type + BugClass* = object + x: int # Not initialized + +proc makeBugClass(): BugClass {.constructor.} = + discard + +proc main = + for i in 0 .. 1: + var n = makeBugClass() + echo n.x + n.x = 123 + echo n.x + +main() \ No newline at end of file