diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim index 407ccf0cd8..d302bd5f70 100644 --- a/compiler/liftdestructors.nim +++ b/compiler/liftdestructors.nim @@ -1188,7 +1188,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 27ea70f3c9..575c4ba47a 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1425,6 +1425,17 @@ proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]], a = a[i] result = a.kind == last +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 @@ -1867,6 +1878,3 @@ proc isCharArrayPtr*(t: PType; allowPointerToChar: bool): bool = result = allowPointerToChar else: discard - -proc lacksMTypeField*(typ: PType): bool {.inline.} = - (typ.sym != nil and sfPure in typ.sym.flags) or tfFinal in typ.flags 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()