From e449813c61fbdbb150b197fca98610424e1107ad Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Wed, 26 Feb 2025 00:08:22 +0800 Subject: [PATCH] fixes #24725; Invalid =sink generated for pure inheritable object (#24726) fixes #24725 `lacksMTypeField` doesn't take the base types into consideration. And for ` {.inheritable, pure.}`, it shouldn't generate a `m_type` field. --- compiler/ccgtypes.nim | 4 ---- compiler/liftdestructors.nim | 2 +- compiler/types.nim | 9 +++++++++ tests/ccgbugs/tcgbug.nim | 18 ++++++++++++++++++ 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 92b439891d..ef7550d2c0 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -247,10 +247,6 @@ proc hasNoInit(t: PType): bool = proc getTypeDescAux(m: BModule; origTyp: PType, check: var IntSet; kind: TypeDescKind): Rope -proc isObjLackingTypeField(typ: PType): bool {.inline.} = - result = (typ.kind == tyObject) and ((tfFinal in typ.flags) and - (typ.baseClass == nil) or isPureObject(typ)) - proc isInvalidReturnType(conf: ConfigRef; typ: PType, isProc = true): bool = # Arrays and sets cannot be returned by a C procedure, because C is # such a poor programming language. diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim index 9020a6f7ff..c948916132 100644 --- a/compiler/liftdestructors.nim +++ b/compiler/liftdestructors.nim @@ -1197,7 +1197,7 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp; fillStrOp(a, typ, result.ast[bodyPos], d, src) else: fillBody(a, typ, result.ast[bodyPos], d, src) - if tk == tyObject and a.kind in {attachedAsgn, attachedSink, attachedDeepCopy, attachedDup} and not lacksMTypeField(typ): + if tk == tyObject and a.kind in {attachedAsgn, attachedSink, attachedDeepCopy, attachedDup} and not isObjLackingTypeField(typ): # bug #19205: Do not forget to also copy the hidden type field: genTypeFieldCopy(a, typ, result.ast[bodyPos], d, src) diff --git a/compiler/types.nim b/compiler/types.nim index 1834acdffa..16853e5ffa 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1485,8 +1485,17 @@ proc commonSuperclass*(a, b: PType): PType = y = y.baseClass proc lacksMTypeField*(typ: PType): bool {.inline.} = + ## Returns true if the type is an object that lacks a m_type field. + ## It doesn't check base classes. (typ.sym != nil and sfPure in typ.sym.flags) or tfFinal in typ.flags +proc isObjLackingTypeField*(typ: PType): bool {.inline.} = + ## Returns true if the type is an object that lacks a type field. + ## Object types that store type headers are not final or pure and + ## have inheritable root types, which are not pure, neither. + result = (typ.kind == tyObject) and ((tfFinal in typ.flags) and + (typ.baseClass == nil) or isPureObject(typ)) + include sizealignoffsetimpl proc computeSize*(conf: ConfigRef; typ: PType): BiggestInt = diff --git a/tests/ccgbugs/tcgbug.nim b/tests/ccgbugs/tcgbug.nim index 2eddc6fddc..0db2b12ea4 100644 --- a/tests/ccgbugs/tcgbug.nim +++ b/tests/ccgbugs/tcgbug.nim @@ -161,3 +161,21 @@ typedef struct { int base; } S; var t = newT() doAssert t.s.base == 1 + +type QObject* {.inheritable, pure.} = object + h*: pointer + +proc `=destroy`(self: var QObject) =discard + +proc `=copy`(dest: var QObject, source: QObject) {.error.} + +type QAbstractItemModel* = object of QObject + +type VTable = ref object + inst: QAbstractItemModel + +proc g() = + var x: VTable = VTable() + x.inst = QAbstractItemModel() + +g()