fixes an old ARC bug: the produced copy/sink operations don't copy the hidden type field for objects with enabled inheritance; fixes #19205 [backport:1.6] (#19232)

This commit is contained in:
Andreas Rumpf 2021-12-09 22:23:16 +01:00 • committed by GitHub
commit 32d4bf3525
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 38 additions and 2 deletions

View file

@ -673,7 +673,7 @@ type
mSwap, mIsNil, mArrToSeq, mSwap, mIsNil, mArrToSeq,
mNewString, mNewStringOfCap, mParseBiggestFloat, mNewString, mNewStringOfCap, mParseBiggestFloat,
mMove, mWasMoved, mDestroy, mTrace, mMove, mWasMoved, mDestroy, mTrace,
mDefault, mUnown, mFinished, mIsolate, mAccessEnv, mReset, mDefault, mUnown, mFinished, mIsolate, mAccessEnv, mAccessTypeField, mReset,
mArray, mOpenArray, mRange, mSet, mSeq, mVarargs, mArray, mOpenArray, mRange, mSet, mSeq, mVarargs,
mRef, mPtr, mVar, mDistinct, mVoid, mTuple, mRef, mPtr, mVar, mDistinct, mVoid, mTuple,
mOrdinal, mIterableType, mOrdinal, mIterableType,

View file

@ -1741,6 +1741,13 @@ proc genGetTypeInfoV2(p: BProc, e: PNode, d: var TLoc) =
# use the dynamic type stored at offset 0: # use the dynamic type stored at offset 0:
putIntoDest(p, d, e, rdMType(p, a, nilCheck)) putIntoDest(p, d, e, rdMType(p, a, nilCheck))
proc genAccessTypeField(p: BProc; e: PNode; d: var TLoc) =
var a: TLoc
initLocExpr(p, e[1], a)
var nilCheck = Rope(nil)
# use the dynamic type stored at offset 0:
putIntoDest(p, d, e, rdMType(p, a, nilCheck))
template genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) = template genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) =
var a: TLoc var a: TLoc
initLocExpr(p, n[1], a) initLocExpr(p, n[1], a)
@ -2449,6 +2456,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
of mMove: genMove(p, e, d) of mMove: genMove(p, e, d)
of mDestroy: genDestroy(p, e) of mDestroy: genDestroy(p, e)
of mAccessEnv: unaryExpr(p, e, d, "$1.ClE_0") of mAccessEnv: unaryExpr(p, e, d, "$1.ClE_0")
of mAccessTypeField: genAccessTypeField(p, e, d)
of mSlice: genSlice(p, e, d) of mSlice: genSlice(p, e, d)
of mTrace: discard "no code to generate" of mTrace: discard "no code to generate"
else: else:

View file

@ -583,7 +583,7 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope,
if typ.kind == tyObject: if typ.kind == tyObject:
if typ[0] == nil: if typ[0] == nil:
if (typ.sym != nil and sfPure in typ.sym.flags) or tfFinal in typ.flags: if lacksMTypeField(typ):
appcg(m, result, " {$n", []) appcg(m, result, " {$n", [])
else: else:
if optTinyRtti in m.config.globalOptions: if optTinyRtti in m.config.globalOptions:

View file

@ -941,6 +941,12 @@ proc symPrototype(g: ModuleGraph; typ: PType; owner: PSym; kind: TTypeAttachedOp
incl result.flags, sfFromGeneric incl result.flags, sfFromGeneric
incl result.flags, sfGeneratedOp incl result.flags, sfGeneratedOp
proc genTypeFieldCopy(c: var TLiftCtx; t: PType; body, x, y: PNode) =
let xx = genBuiltin(c, mAccessTypeField, "accessTypeField", x)
let yy = genBuiltin(c, mAccessTypeField, "accessTypeField", y)
xx.typ = getSysType(c.g, c.info, tyPointer)
yy.typ = xx.typ
body.add newAsgnStmt(xx, yy)
proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp; proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
info: TLineInfo; idgen: IdGenerator): PSym = info: TLineInfo; idgen: IdGenerator): PSym =
@ -980,6 +986,10 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
fillStrOp(a, typ, result.ast[bodyPos], d, src) fillStrOp(a, typ, result.ast[bodyPos], d, src)
else: else:
fillBody(a, typ, result.ast[bodyPos], d, src) fillBody(a, typ, result.ast[bodyPos], d, src)
if tk == tyObject and a.kind in {attachedAsgn, attachedSink, attachedDeepCopy} and not lacksMTypeField(typ):
# bug #19205: Do not forget to also copy the hidden type field:
genTypeFieldCopy(a, typ, result.ast[bodyPos], d, src)
if not a.canRaise: incl result.flags, sfNeverRaises if not a.canRaise: incl result.flags, sfNeverRaises
completePartialOp(g, idgen.module, typ, kind, result) completePartialOp(g, idgen.module, typ, kind, result)

View file

@ -1705,3 +1705,6 @@ proc isCharArrayPtr*(t: PType; allowPointerToChar: bool): bool =
result = allowPointerToChar result = allowPointerToChar
else: else:
discard discard
proc lacksMTypeField*(typ: PType): bool {.inline.} =
(typ.sym != nil and sfPure in typ.sym.flags) or tfFinal in typ.flags

View file

@ -30,6 +30,7 @@ ok
true true
copying copying
123 123
42
closed closed
destroying variable: 20 destroying variable: 20
destroying variable: 10 destroying variable: 10
@ -482,3 +483,17 @@ method testMethod(self: BrokenObject) {.base.} =
let mikasa = BrokenObject() let mikasa = BrokenObject()
mikasa.testMethod() mikasa.testMethod()
# bug #19205
type
InputSectionBase* = object of RootObj
relocations*: seq[int] # traced reference. string has a similar SIGSEGV.
InputSection* = object of InputSectionBase
proc fooz(sec: var InputSectionBase) =
if sec of InputSection: # this line SIGSEGV.
echo 42
var sec = create(InputSection)
sec[] = InputSection(relocations: newSeq[int]())
fooz sec[]