From 2c2ec48bc493db39ff1c6aa30e93b227c8e2a096 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Tue, 11 May 2021 16:21:29 +0200 Subject: [PATCH] ORC: critical bugfix for mixing acyclic refs with cyclic refs [backport:1.4] (#17991) --- compiler/liftdestructors.nim | 17 ++++++++++------- compiler/types.nim | 3 ++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim index ec0435f95a..1dc711bd6b 100644 --- a/compiler/liftdestructors.nim +++ b/compiler/liftdestructors.nim @@ -652,16 +652,19 @@ proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = body.add genIf(c, cond, actions) of attachedDeepCopy: assert(false, "cannot happen") of attachedTrace: - if isFinal(elemType): - let typInfo = genBuiltin(c, mGetTypeInfoV2, "getTypeInfoV2", newNodeIT(nkType, x.info, elemType)) - typInfo.typ = getSysType(c.g, c.info, tyPointer) - body.add callCodegenProc(c.g, "nimTraceRef", c.info, genAddrOf(x, c.idgen), typInfo, y) - else: - # If the ref is polymorphic we have to account for this - body.add callCodegenProc(c.g, "nimTraceRefDyn", c.info, genAddrOf(x, c.idgen), y) + if isCyclic: + if isFinal(elemType): + let typInfo = genBuiltin(c, mGetTypeInfoV2, "getTypeInfoV2", newNodeIT(nkType, x.info, elemType)) + typInfo.typ = getSysType(c.g, c.info, tyPointer) + body.add callCodegenProc(c.g, "nimTraceRef", c.info, genAddrOf(x, c.idgen), typInfo, y) + else: + # If the ref is polymorphic we have to account for this + body.add callCodegenProc(c.g, "nimTraceRefDyn", c.info, genAddrOf(x, c.idgen), y) of attachedDispose: # this is crucial! dispose is like =destroy but we don't follow refs # as that is dealt within the cycle collector. + if not isCyclic: + body.add genIf(c, cond, actions) when false: let cond = copyTree(x) cond.typ = getSysType(c.g, x.info, tyBool) diff --git a/compiler/types.nim b/compiler/types.nim index afa4d74202..cd67d1ad96 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -381,7 +381,8 @@ proc isFinal*(t: PType): bool = proc canFormAcycle*(typ: PType): bool = var marker = initIntSet() - result = canFormAcycleAux(marker, typ, typ.id) + let t = skipTypes(typ, abstractInst+{tyOwned}-{tyTypeDesc}) + result = canFormAcycleAux(marker, t, t.id) proc mutateTypeAux(marker: var IntSet, t: PType, iter: TTypeMutator, closure: RootRef): PType