summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ast.nim2
-rw-r--r--tests/parallel/tptr_to_ref.nim26
2 files changed, 27 insertions, 1 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index c349f81ed..c141352cb 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -1346,7 +1346,7 @@ proc propagateToOwner*(owner, elem: PType) =
       owner.flags.incl tfHasAsgn
 
   if owner.kind notin {tyProc, tyGenericInst, tyGenericBody,
-                       tyGenericInvocation}:
+                       tyGenericInvocation, tyPtr}:
     let elemB = elem.skipTypes({tyGenericInst})
     if elemB.isGCedMem or tfHasGCedMem in elemB.flags:
       # for simplicity, we propagate this flag even to generics. We then
diff --git a/tests/parallel/tptr_to_ref.nim b/tests/parallel/tptr_to_ref.nim
new file mode 100644
index 000000000..66d618481
--- /dev/null
+++ b/tests/parallel/tptr_to_ref.nim
@@ -0,0 +1,26 @@
+# bug #2854
+
+import locks, threadpool, osproc
+
+const MAX_WORKERS = 10
+
+type
+  Killer = object
+    lock: Lock
+    bailed {.guard: lock.}: bool
+    processes {.guard: lock.}: array[0..MAX_WORKERS-1, foreign ptr Process]
+
+template hold(lock: Lock, body: stmt) =
+  lock.acquire
+  defer: lock.release
+  {.locks: [lock].}:
+    body
+
+proc initKiller*(): Killer =
+  initLock(result.lock)
+  result.lock.hold:
+    result.bailed = false
+    for i, _ in result.processes:
+      result.processes[i] = nil
+
+var killer = initKiller()