summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-11-02 14:35:13 +0100
committerAraq <rumpf_a@web.de>2014-11-02 14:35:13 +0100
commitc4d05ca130e944cb10ba1ec40ffafe0a7f83b58a (patch)
tree5d8bde50c270245140545751188762583dc822d5
parentdac43e0fdd393c3267040e91e95592ba184a4527 (diff)
downloadNim-c4d05ca130e944cb10ba1ec40ffafe0a7f83b58a.tar.gz
better effect inference
-rw-r--r--compiler/sempass2.nim25
-rw-r--r--tests/effects/teffects1.nim2
2 files changed, 18 insertions, 9 deletions
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index cbabc755b..0d8c7c479 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -181,6 +181,10 @@ proc initVarViaNew(a: PEffects, n: PNode) =
     # are initialized:
     initVar(a, n)
 
+proc warnAboutGcUnsafe(n: PNode) =
+  #assert false
+  message(n.info, warnGcUnsafe, renderTree(n))
+
 proc useVar(a: PEffects, n: PNode) =
   let s = n.sym
   if isLocalVar(a, s):
@@ -195,7 +199,7 @@ proc useVar(a: PEffects, n: PNode) =
     if s.guard != nil: guardGlobal(a, n, s.guard)
     if (tfHasGCedMem in s.typ.flags or s.typ.isGCedMem) and 
         tfGcSafe notin s.typ.flags:
-      if warnGcUnsafe in gNotes: message(n.info, warnGcUnsafe, renderTree(n))
+      if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n)
       a.gcUnsafe = true
 
 type
@@ -431,7 +435,7 @@ proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) =
   mergeTags(tracked, tagSpec, n)
 
   if notGcSafe(s.typ) and sfImportc notin s.flags:
-    if warnGcUnsafe in gNotes: message(n.info, warnGcUnsafe, renderTree(n))
+    if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n)
     tracked.gcUnsafe = true
   mergeLockLevels(tracked, n, s.getLockLevel)
 
@@ -462,8 +466,13 @@ proc assumeTheWorst(tracked: PEffects; n: PNode; op: PType) =
   #  message(n.info, warnUser, "had to assume the worst here")
   mergeLockLevels(tracked, n, lockLevel)
 
+proc isOwnedProcVar(n: PNode; owner: PSym): bool =
+  # XXX prove the soundness of this effect system rule
+  result = n.kind == nkSym and n.sym.kind == skParam and owner == n.sym.owner
+
 proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) =
-  let op = skipConvAndClosure(n).typ
+  let a = skipConvAndClosure(n)
+  let op = a.typ
   if op != nil and op.kind == tyProc and n.kind != nkNilLit:
     internalAssert op.n.sons[0].kind == nkEffectList
     var effectList = op.n.sons[0]
@@ -475,18 +484,18 @@ proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) =
         # we have no explicit effects but it's a forward declaration and so it's
         # stated there are no additional effects, so simply propagate them:
         propagateEffects(tracked, n, n.sym)
-      else:
+      elif not isOwnedProcVar(a, tracked.owner):
         # we have no explicit effects so assume the worst:
         assumeTheWorst(tracked, n, op)
       # assume GcUnsafe unless in its type; 'forward' does not matter:
-      if notGcSafe(op):
-        if warnGcUnsafe in gNotes: message(n.info, warnGcUnsafe, renderTree(n))
+      if notGcSafe(op) and not isOwnedProcVar(a, tracked.owner):
+        if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n)
         tracked.gcUnsafe = true
     else:
       mergeEffects(tracked, effectList.sons[exceptionEffects], n)
       mergeTags(tracked, effectList.sons[tagEffects], n)
       if notGcSafe(op):
-        if warnGcUnsafe in gNotes: message(n.info, warnGcUnsafe, renderTree(n))
+        if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n)
         tracked.gcUnsafe = true
   notNilCheck(tracked, n, paramType)
 
@@ -633,7 +642,7 @@ proc track(tracked: PEffects, n: PNode) =
         if notGcSafe(op) and not importedFromC(a):
           # and it's not a recursive call:
           if not (a.kind == nkSym and a.sym == tracked.owner):
-            message(n.info, warnGcUnsafe, renderTree(n))
+            warnAboutGcUnsafe(n)
             tracked.gcUnsafe = true
     for i in 1 .. <len(n): trackOperand(tracked, n.sons[i], paramType(op, i))
     if a.kind == nkSym and a.sym.magic in {mNew, mNewFinalize, mNewSeq}:
diff --git a/tests/effects/teffects1.nim b/tests/effects/teffects1.nim
index e6d38cbc2..e32096b57 100644
--- a/tests/effects/teffects1.nim
+++ b/tests/effects/teffects1.nim
@@ -1,5 +1,5 @@
 discard """
-  line: 2169
+  line: 2170
   file: "system.nim"
   errormsg: "can raise an unlisted exception: ref IOError"
 """