diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 2473db70de..ff43c003d5 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -514,18 +514,21 @@ proc genRecordFieldsAux(m: BModule, n: PNode, let structName = "_" & mangleRecFieldName(m, n[0].sym) & "_" & $i var a = newRopeAppender() genRecordFieldsAux(m, k, rectype, check, a, unionPrefix & $structName & ".") - if a != "": - if tfPacked notin rectype.flags: - unionBody.add("struct {") + # When 'k' is 'void', 'a' is the empty string and we just generate + # empty struct. This prevents field access errors when generating + # static initializers for the type. + # See issue #20699 + if tfPacked notin rectype.flags: + unionBody.add("struct {") + else: + if hasAttribute in CC[m.config.cCompiler].props: + unionBody.add("struct __attribute__((__packed__)){") else: - if hasAttribute in CC[m.config.cCompiler].props: - unionBody.add("struct __attribute__((__packed__)){") - else: - unionBody.addf("#pragma pack(push, 1)$nstruct{", []) - unionBody.add(a) - unionBody.addf("} $1;$n", [structName]) - if tfPacked in rectype.flags and hasAttribute notin CC[m.config.cCompiler].props: - unionBody.addf("#pragma pack(pop)$n", []) + unionBody.addf("#pragma pack(push, 1)$nstruct{", []) + unionBody.add(a) + unionBody.addf("} $1;$n", [structName]) + if tfPacked in rectype.flags and hasAttribute notin CC[m.config.cCompiler].props: + unionBody.addf("#pragma pack(pop)$n", []) else: genRecordFieldsAux(m, k, rectype, check, unionBody, unionPrefix) else: internalError(m.config, "genRecordFieldsAux(record case branch)") diff --git a/tests/objects/tobject_default_value.nim b/tests/objects/tobject_default_value.nim index 85be43daa1..65dae64ff3 100644 --- a/tests/objects/tobject_default_value.nim +++ b/tests/objects/tobject_default_value.nim @@ -476,6 +476,20 @@ template main {.dirty.} = foo2() + block: # issue #20699 + type + Either[A,B] = object + case kind:bool + of false: + b: B + of true: + a: A + O = object of RootRef + + proc oToEither(o:O):Either[O,void] = + Either[O,void](kind:true,a: o) + + discard oToEither(O()) static: main() main()