summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorringabout <43030857+ringabout@users.noreply.github.com>2023-07-10 16:31:13 +0800
committerGitHub <noreply@github.com>2023-07-10 10:31:13 +0200
commitecc6ab7ee06a5969fd871585de8b93120bd58a2b (patch)
tree841478f537c16b6a44ccc6a21a2b31e9e7f528fe
parent1b132ddaa2734fc43a9c172407fc968cfeec4a24 (diff)
downloadNim-ecc6ab7ee06a5969fd871585de8b93120bd58a2b.tar.gz
fixes #22237; fixes #21160; wrong cursor on unowned parameters in the for loop in ORC (#22240)
fixes #22237; fixes #21160; wrong cursor on unowned parameters
-rw-r--r--compiler/transf.nim17
-rw-r--r--tests/arc/t22237.nim55
2 files changed, 70 insertions, 2 deletions
diff --git a/compiler/transf.nim b/compiler/transf.nim
index 6ff1da899..d0428b725 100644
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -654,7 +654,7 @@ proc findWrongOwners(c: PTransf, n: PNode) =
   else:
     for i in 0..<n.safeLen: findWrongOwners(c, n[i])
 
-proc isSimpleIteratorVar(c: PTransf; iter: PSym): bool =
+proc isSimpleIteratorVar(c: PTransf; iter: PSym; call: PNode; owner: PSym): bool =
   proc rec(n: PNode; owner: PSym; dangerousYields: var int) =
     case n.kind
     of nkEmpty..nkNilLit: discard
@@ -666,9 +666,22 @@ proc isSimpleIteratorVar(c: PTransf; iter: PSym): bool =
     else:
       for c in n: rec(c, owner, dangerousYields)
 
+  proc recSym(n: PNode; owner: PSym; sameOwner: var bool) =
+    case n.kind
+    of {nkEmpty..nkNilLit} - {nkSym}: discard
+    of nkSym:
+      if n.sym.owner != owner:
+        sameOwner = false
+    else:
+      for c in n: recSym(c, owner, sameOwner)
+
   var dangerousYields = 0
   rec(getBody(c.graph, iter), iter, dangerousYields)
   result = dangerousYields == 0
+  # the parameters should be owned by the owner
+  # bug #22237
+  for i in 1..<call.len:
+    recSym(call[i], owner, result)
 
 template destructor(t: PType): PSym = getAttachedOp(c.graph, t, attachedDestructor)
 
@@ -712,7 +725,7 @@ proc transformFor(c: PTransf, n: PNode): PNode =
       for j in 0..<n[i].len-1:
         addVar(v, copyTree(n[i][j])) # declare new vars
     else:
-      if n[i].kind == nkSym and isSimpleIteratorVar(c, iter):
+      if n[i].kind == nkSym and isSimpleIteratorVar(c, iter, call, n[i].sym.owner):
         incl n[i].sym.flags, sfCursor
       addVar(v, copyTree(n[i])) # declare new vars
   stmtList.add(v)
diff --git a/tests/arc/t22237.nim b/tests/arc/t22237.nim
new file mode 100644
index 000000000..c6dbf768a
--- /dev/null
+++ b/tests/arc/t22237.nim
@@ -0,0 +1,55 @@
+discard """
+  matrix: "--mm:arc; --mm:orc"
+"""
+
+import std/macros
+import std/streams
+
+# bug #22237
+
+proc iterlines_closure2(f: File | Stream): iterator (): string =
+  result = iterator(): string =
+    for line in f.lines:
+      if line.len == 0:
+        break
+      yield line
+
+proc test() =
+  let f = newStringStream("""
+    1
+    2
+
+    3
+    4
+
+    5
+    6
+    7
+
+    8
+""")
+  while not f.atEnd():
+    let iterator_inst = iterlines_closure2(f)
+    for item in iterator_inst(): # Fails with "SIGSEGV: Illegal storage access. (Attempt to read from nil?)"
+      discard
+
+test()
+
+# bug #21160
+import sequtils
+
+iterator allMoves(fls: seq[int]): seq[int] =
+  yield fls
+
+proc neighbors(flrs: seq[int]): iterator: seq[int] =
+  return iterator(): seq[int] =
+    for flrs2 in allMoves(flrs):
+      yield flrs2
+      for flrs3 in allMoves(flrs2):
+        yield flrs3
+
+let f = @[1]
+for _ in neighbors(f):
+  discard
+for _ in neighbors(f):
+  discard