summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/sempass2.nim10
-rw-r--r--tests/effects/tgcsafe.nim11
2 files changed, 17 insertions, 4 deletions
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index b453971c2..923558a8d 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -572,10 +572,14 @@ proc isNoEffectList(n: PNode): bool {.inline.} =
   assert n.kind == nkEffectList
   n.len == 0 or (n[tagEffects] == nil and n[exceptionEffects] == nil)
 
-proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) =
+proc isTrival(caller: PNode): bool {.inline.} =
+  result = caller.kind == nkSym and caller.sym.magic in {mEqProc, mIsNil}
+
+proc trackOperand(tracked: PEffects, n: PNode, paramType: PType; caller: PNode) =
   let a = skipConvAndClosure(n)
   let op = a.typ
-  if op != nil and op.kind == tyProc and n.skipConv.kind != nkNilLit:
+  # assume indirect calls are taken here:
+  if op != nil and op.kind == tyProc and n.skipConv.kind != nkNilLit and not isTrival(caller):
     internalAssert tracked.config, op.n.sons[0].kind == nkEffectList
     var effectList = op.n.sons[0]
     var s = n.skipConv
@@ -773,7 +777,7 @@ proc track(tracked: PEffects, n: PNode) =
           if not (a.kind == nkSym and a.sym == tracked.owner):
             markSideEffect(tracked, a)
     if a.kind != nkSym or a.sym.magic != mNBindSym:
-      for i in 1 ..< len(n): trackOperand(tracked, n.sons[i], paramType(op, i))
+      for i in 1 ..< len(n): trackOperand(tracked, n.sons[i], paramType(op, i), a)
     if a.kind == nkSym and a.sym.magic in {mNew, mNewFinalize, mNewSeq}:
       # may not look like an assignment, but it is:
       let arg = n.sons[1]
diff --git a/tests/effects/tgcsafe.nim b/tests/effects/tgcsafe.nim
index ff207df59..363624f19 100644
--- a/tests/effects/tgcsafe.nim
+++ b/tests/effects/tgcsafe.nim
@@ -1,9 +1,18 @@
 discard """
   errormsg: "'mainUnsafe' is not GC-safe"
-  line: 17
+  line: 26
   cmd: "nim $target --hints:on --threads:on $options $file"
 """
 
+# bug #6955
+var global_proc: proc(a: string): int {.nimcall.} = nil
+
+proc myproc(i: int) {.gcsafe.} =
+  if global_proc != nil:
+    echo "a"
+  if isNil(global_proc):
+    return
+
 proc mymap(x: proc ()) =
   x()