summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/destroyer.nim45
1 files changed, 23 insertions, 22 deletions
diff --git a/compiler/destroyer.nim b/compiler/destroyer.nim
index b81f6c0fc..ee930018a 100644
--- a/compiler/destroyer.nim
+++ b/compiler/destroyer.nim
@@ -411,10 +411,12 @@ proc passCopyToSink(n: PNode; c: var Con): PNode =
   result.add tmp
 
 proc pArg(arg: PNode; c: var Con; isSink: bool): PNode =
-  if arg.typ == nil:
-    # typ is nil if we are in if/case branch with noreturn
-    result = copyTree(arg)
-  elif isSink:
+  template pArgIfTyped(arg_part: PNode): PNode =
+    # typ is nil if we are in if/case expr branch with noreturn
+    if arg_part.typ == nil: copyTree(arg_part)
+    else: pArg(arg_part, c, isSink)
+  
+  if isSink:
     if arg.kind in nkCallKinds:
       # recurse but skip the call expression in order to prevent
       # destructor injections: Rule 5.1 is different from rule 5.4!
@@ -446,9 +448,9 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode =
         var branch = copyNode(arg[i])
         if arg[i].kind in {nkElifBranch, nkElifExpr}:   
           branch.add p(arg[i][0], c)
-          branch.add pArg(arg[i][1], c, isSink)
+          branch.add pArgIfTyped(arg[i][1])
         else:
-          branch.add pArg(arg[i][0], c, isSink)
+          branch.add pArgIfTyped(arg[i][0])
         result.add branch
     elif arg.kind == nkCaseStmt:
       result = copyNode(arg)
@@ -457,14 +459,14 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode =
         var branch: PNode
         if arg[i].kind == nkOfbranch:
           branch = arg[i] # of branch conditions are constants
-          branch[^1] = pArg(arg[i][^1], c, isSink)
+          branch[^1] = pArgIfTyped(arg[i][^1])
         elif arg[i].kind in {nkElifBranch, nkElifExpr}:
           branch = copyNode(arg[i])   
           branch.add p(arg[i][0], c)
-          branch.add pArg(arg[i][1], c, isSink)
+          branch.add pArgIfTyped(arg[i][1])
         else:
           branch = copyNode(arg[i]) 
-          branch.add pArg(arg[i][0], c, isSink)
+          branch.add pArgIfTyped(arg[i][0])
         result.add branch     
     else:
       # an object that is not temporary but passed to a 'sink' parameter
@@ -474,11 +476,12 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode =
     result = p(arg, c)
 
 proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
-  if ri.typ == nil:
-    # typ is nil if we are in if/case branch with noreturn
-    result = copyTree(ri)
-  else:
-    case ri.kind
+  template moveOrCopyIfTyped(ri_part: PNode): PNode =
+    # typ is nil if we are in if/case expr branch with noreturn
+    if ri_part.typ == nil: copyTree(ri_part)
+    else: moveOrCopy(dest, ri_part, c)
+
+  case ri.kind
     of nkCallKinds:
       result = genSink(c, dest.typ, dest, ri)
       # watch out and no not transform 'ri' twice if it's a call:
@@ -505,18 +508,16 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
     of nkBlockExpr, nkBlockStmt:
       result = newNodeI(nkBlockStmt, ri.info)
       result.add ri[0] ## add label
-      for i in 1..ri.len-2:
-        result.add p(ri[i], c)
-      result.add moveOrCopy(dest, ri[^1], c)
+      result.add moveOrCopy(dest, ri[1], c)
     of nkIfExpr, nkIfStmt:
       result = newNodeI(nkIfStmt, ri.info)
       for i in 0..<ri.len:
         var branch = copyNode(ri[i])
         if ri[i].kind in {nkElifBranch, nkElifExpr}:
           branch.add p(ri[i][0], c)
-          branch.add moveOrCopy(dest, ri[i][1], c)
+          branch.add moveOrCopyIfTyped(ri[i][1])
         else:
-          branch.add moveOrCopy(dest, ri[i][0], c)
+          branch.add moveOrCopyIfTyped(ri[i][0])
         result.add branch
     of nkCaseStmt:
       result = newNodeI(nkCaseStmt, ri.info)
@@ -525,14 +526,14 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
         var branch: PNode
         if ri[i].kind == nkOfbranch:
           branch = ri[i] # of branch conditions are constants
-          branch[^1] = moveOrCopy(dest, ri[i][^1], c)
+          branch[^1] = moveOrCopyIfTyped(ri[i][^1])
         elif ri[i].kind in {nkElifBranch, nkElifExpr}:
           branch = copyNode(ri[i])   
           branch.add p(ri[i][0], c)
-          branch.add moveOrCopy(dest, ri[i][1], c)
+          branch.add moveOrCopyIfTyped(ri[i][1])
         else:
           branch = copyNode(ri[i]) 
-          branch.add moveOrCopy(dest, ri[i][0], c)
+          branch.add moveOrCopyIfTyped(ri[i][0])
         result.add branch
     of nkObjConstr:
       result = genSink(c, dest.typ, dest, ri)