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 e449813c61)
This commit is contained in:
ringabout
2025-02-26 00:08:22 +08:00
committed by narimiran
parent d2b8c3c0d5
commit edeac84e47
3 changed files with 30 additions and 4 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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()