diff options
-rw-r--r-- | compiler/sempass2.nim | 15 | ||||
-rw-r--r-- | tests/effects/tgcsafe2.nim | 12 |
2 files changed, 15 insertions, 12 deletions
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 9ce317f80..e9a1160e5 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -19,18 +19,6 @@ when defined(useDfa): # # * effect+exception tracking # * "usage before definition" checking -# * checks for invalid usages of compiletime magics (not implemented) -# * checks for invalid usages of NimNode (not implemented) -# * later: will do an escape analysis for closures at least - -# Predefined effects: -# io, time (time dependent), gc (performs GC'ed allocation), exceptions, -# side effect (accesses global), store (stores into *type*), -# store_unknown (performs some store) --> store(any)|store(x) -# load (loads from *type*), recursive (recursive call), unsafe, -# endless (has endless loops), --> user effects are defined over *patterns* -# --> a TR macro can annotate the proc with user defined annotations -# --> the effect system can access these # ------------------------ exception and tag tracking ------------------------- @@ -593,6 +581,9 @@ proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) = if paramType != nil and paramType.kind == tyVar: if n.kind == nkSym and isLocalVar(tracked, n.sym): makeVolatile(tracked, n.sym) + if paramType != nil and paramType.kind == tyProc and tfGcSafe in paramType.flags: + if tfGcSafe notin a.typ.flags and not tracked.inEnforcedGcSafe: + localError(n.info, $n & " is not GC safe") notNilCheck(tracked, n, paramType) proc breaksBlock(n: PNode): bool = diff --git a/tests/effects/tgcsafe2.nim b/tests/effects/tgcsafe2.nim new file mode 100644 index 000000000..dbc4540c4 --- /dev/null +++ b/tests/effects/tgcsafe2.nim @@ -0,0 +1,12 @@ +discard """ + errormsg: ''' (proc (s: string) = res &= &(s, "abc"), nil) is not GC safe''' + line: 11 +""" +#5620 +var res = "" + +proc takeCallback(foo: (proc(s: string) {.gcsafe.})) = + foo "string" + +takeCallback(proc (s: string) = + res &= s & "abc") |