From edeac84e476fe77edfdf693d69d2bf9a912a5e05 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. (cherry picked from commit e449813c61fbdbb150b197fca98610424e1107ad) --- compiler/liftdestructors.nim | 2 +- compiler/types.nim | 14 +++++++++++--- tests/ccgbugs/tcgbug.nim | 18 ++++++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) 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()