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.nim33
1 files changed, 25 insertions, 8 deletions
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index 75dea069f..b453971c2 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -232,7 +232,10 @@ proc listGcUnsafety(s: PSym; onlyWarning: bool; conf: ConfigRef) =
 proc useVar(a: PEffects, n: PNode) =
   let s = n.sym
   if isLocalVar(a, s):
-    if s.id notin a.init:
+    if sfNoInit in s.flags:
+      # If the variable is explicitly marked as .noinit. do not emit any error
+      a.init.add s.id
+    elif s.id notin a.init:
       if {tfNeedsInit, tfNotNil} * s.typ.flags != {}:
         message(a.config, n.info, warnProveInit, s.name.s)
       else:
@@ -353,6 +356,8 @@ proc trackTryStmt(tracked: PEffects, n: PNode) =
 
   var branches = 1
   var hasFinally = false
+
+  # Collect the exceptions caught by the except branches
   for i in 1 ..< n.len:
     let b = n.sons[i]
     let blen = sonsLen(b)
@@ -368,12 +373,18 @@ proc trackTryStmt(tracked: PEffects, n: PNode) =
           else:
             assert(b.sons[j].kind == nkType)
             catches(tracked, b.sons[j].typ)
+    else:
+      assert b.kind == nkFinally
+  # Add any other exception raised in the except bodies
+  for i in 1 ..< n.len:
+    let b = n.sons[i]
+    let blen = sonsLen(b)
+    if b.kind == nkExceptBranch:
       setLen(tracked.init, oldState)
       track(tracked, b.sons[blen-1])
       for i in oldState..<tracked.init.len:
         addToIntersection(inter, tracked.init[i])
     else:
-      assert b.kind == nkFinally
       setLen(tracked.init, oldState)
       track(tracked, b.sons[blen-1])
       hasFinally = true
@@ -710,11 +721,17 @@ proc track(tracked: PEffects, n: PNode) =
   of nkSym:
     useVar(tracked, n)
   of nkRaiseStmt:
-    n.sons[0].info = n.info
-    #throws(tracked.exc, n.sons[0])
-    addEffect(tracked, n.sons[0], useLineInfo=false)
-    for i in 0 ..< safeLen(n):
-      track(tracked, n.sons[i])
+    if n[0].kind != nkEmpty:
+      n.sons[0].info = n.info
+      #throws(tracked.exc, n.sons[0])
+      addEffect(tracked, n.sons[0], useLineInfo=false)
+      for i in 0 ..< safeLen(n):
+        track(tracked, n.sons[i])
+    else:
+      # A `raise` with no arguments means we're going to re-raise the exception
+      # being handled or, if outside of an `except` block, a `ReraiseError`.
+      # Here we add a `Exception` tag in order to cover both the cases.
+      addEffect(tracked, createRaise(tracked.graph, n))
   of nkCallKinds:
     if getConstExpr(tracked.owner_module, n, tracked.graph) != nil:
       return
@@ -1013,7 +1030,7 @@ proc trackProc*(g: ModuleGraph; s: PSym, body: PNode) =
       "declared lock level is $1, but real lock level is $2" %
         [$s.typ.lockLevel, $t.maxLockLevel])
   when defined(useDfa):
-    if s.kind == skFunc:
+    if s.name.s == "testp":
       dataflowAnalysis(s, body)
       when false: trackWrites(s, body)