summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2021-05-11 16:21:29 +0200
committerGitHub <noreply@github.com>2021-05-11 16:21:29 +0200
commit2c2ec48bc493db39ff1c6aa30e93b227c8e2a096 (patch)
tree32bbcf55c5c005c478598210e28bc5b2099d8d13 /compiler
parent45490497e33d37a55846f3e0422134a5051773a1 (diff)
downloadNim-2c2ec48bc493db39ff1c6aa30e93b227c8e2a096.tar.gz
ORC: critical bugfix for mixing acyclic refs with cyclic refs [backport:1.4] (#17991)
Diffstat (limited to 'compiler')
-rw-r--r--compiler/liftdestructors.nim17
-rw-r--r--compiler/types.nim3
2 files changed, 12 insertions, 8 deletions
diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim
index ec0435f95..1dc711bd6 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 afa4d7420..cd67d1ad9 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