summary refs log tree commit diff stats
path: root/compiler/sempass2.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/sempass2.nim')
-rw-r--r--compiler/sempass2.nim20
1 files changed, 13 insertions, 7 deletions
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index b2b91490c..6235fb76a 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -71,7 +71,7 @@ type
     init: seq[int] # list of initialized variables
     guards: TModel # nested guards
     locked: seq[PNode] # locked locations
-    gcUnsafe: bool
+    gcUnsafe, isRecursive: bool
   PEffects = var TEffects
 
 proc isLocalVar(a: PEffects, s: PSym): bool =
@@ -113,7 +113,8 @@ proc useVar(a: PEffects, n: PNode) =
   if {sfGlobal, sfThread} * s.flags == {sfGlobal} and s.kind == skVar:
     when trackGlobals:
       a.addUse(copyNode(n))
-    if tfHasGCedMem in s.typ.flags: 
+    if (tfHasGCedMem in s.typ.flags or s.typ.isGCedMem) and 
+        tfGcSafe notin s.typ.flags:
       message(n.info, warnGcUnsafe, renderTree(n))
       a.gcUnsafe = true
 
@@ -502,7 +503,9 @@ proc track(tracked: PEffects, n: PNode) =
     # are indistinguishable from normal procs (both have tyProc type) and
     # we can detect them only by checking for attached nkEffectList.
     if op != nil and op.kind == tyProc and op.n.sons[0].kind == nkEffectList:
-      if notGcSafe(op) and not importedFromC(a):
+      if a.kind == nkSym and a.sym == tracked.owner:
+        tracked.isRecursive = true
+      elif notGcSafe(op) and not importedFromC(a):
         message(n.info, warnGcUnsafe, renderTree(n))
         tracked.gcUnsafe = true
       var effectList = op.n.sons[0]
@@ -515,6 +518,7 @@ proc track(tracked: PEffects, n: PNode) =
           addEffect(tracked, createRaise(n))
           addTag(tracked, createTag(n))
           when trackGlobals: addUse(tracked, createAnyGlobal(n))
+          # XXX handle 'gcsafe' properly for callbacks!
       else:
         mergeEffects(tracked, effectList.sons[exceptionEffects], n)
         mergeTags(tracked, effectList.sons[tagEffects], n)
@@ -701,10 +705,12 @@ proc trackProc*(s: PSym, body: PNode) =
       checkRaisesSpec(usesSpec, t.uses,
         "uses an unlisted global variable: ", hints=on, symbolPredicate)
       effects.sons[usesEffects] = usesSpec
-  if sfThread in s.flags and t.gcUnsafe:
-    localError(s.info, "'$1' is not GC-safe" % s.name.s)
-  if not t.gcUnsafe: s.typ.flags.incl tfGcSafe
-  
+  if optThreadAnalysis in gGlobalOptions:
+    if sfThread in s.flags and t.gcUnsafe:
+      localError(s.info, warnGcUnsafe2, s.name.s)
+      #localError(s.info, "'$1' is not GC-safe" % s.name.s)
+    if not t.gcUnsafe: s.typ.flags.incl tfGcSafe
+
 proc trackTopLevelStmt*(module: PSym; n: PNode) =
   if n.kind in {nkPragma, nkMacroDef, nkTemplateDef, nkProcDef,
                 nkTypeSection, nkConverterDef, nkMethodDef, nkIteratorDef}: