diff options
-rw-r--r-- | compiler/sempass2.nim | 10 | ||||
-rw-r--r-- | tests/effects/tgcsafe.nim | 11 |
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() |