summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorLemonBoy <LemonBoy@users.noreply.github.com>2018-08-14 20:38:04 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-08-14 20:38:04 +0200
commitc04404635b9efa2d6642887ca40f6222c54d9465 (patch)
treea00d4094e0085d021360c03e90aa0abd08b47f54 /compiler
parent9a7e6be62f6ee8818c6ef2f1504a6dd75774a616 (diff)
downloadNim-c04404635b9efa2d6642887ca40f6222c54d9465.tar.gz
Fix unsound transform pass (#8633)
When a `var openArray[T]` function parameter goes trough the
`transformAddrDeref` pass we may lose the `var` specifier, leading to
nasty crashes at runtime.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ast.nim8
-rw-r--r--compiler/astalgo.nim2
-rw-r--r--compiler/transf.nim4
3 files changed, 14 insertions, 0 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index ef12e1184..e686160dc 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -1674,6 +1674,14 @@ proc skipStmtList*(n: PNode): PNode =
   else:
     result = n
 
+proc toVar*(typ: PType): PType =
+  ## If ``typ`` is not a tyVar then it is converted into a `var <typ>` and
+  ## returned. Otherwise ``typ`` is simply returned as-is.
+  result = typ
+  if typ.kind != tyVar:
+    result = newType(tyVar, typ.owner)
+    rawAddSon(result, typ)
+
 proc toRef*(typ: PType): PType =
   ## If ``typ`` is a tyObject then it is converted into a `ref <typ>` and
   ## returned. Otherwise ``typ`` is simply returned as-is.
diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim
index 333376f6a..152802ba1 100644
--- a/compiler/astalgo.nim
+++ b/compiler/astalgo.nim
@@ -412,6 +412,8 @@ proc debugTree(conf: ConfigRef; n: PNode, indent: int, maxRecDepth: int;
         else:
           addf(result, ",$N$1\"ident\": null", [istr])
       else:
+        if renderType and n.typ != nil:
+          addf(result, ",$N$1\"typ\": $2", [istr, debugType(conf, n.typ, 2)])
         if sonsLen(n) > 0:
           addf(result, ",$N$1\"sons\": [", [istr])
           for i in countup(0, sonsLen(n) - 1):
diff --git a/compiler/transf.nim b/compiler/transf.nim
index c3bc29891..3a276dc38 100644
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -369,6 +369,8 @@ proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode =
       result = PTransNode(n.sons[0])
       if n.typ.skipTypes(abstractVar).kind != tyOpenArray:
         PNode(result).typ = n.typ
+      elif n.typ.skipTypes(abstractInst).kind in {tyVar}:
+        PNode(result).typ = toVar(PNode(result).typ)
   of nkHiddenStdConv, nkHiddenSubConv, nkConv:
     var m = n.sons[0].sons[1]
     if m.kind == a or m.kind == b:
@@ -377,6 +379,8 @@ proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode =
       result = PTransNode(n.sons[0])
       if n.typ.skipTypes(abstractVar).kind != tyOpenArray:
         PNode(result).typ = n.typ
+      elif n.typ.skipTypes(abstractInst).kind in {tyVar}:
+        PNode(result).typ = toVar(PNode(result).typ)
   else:
     if n.sons[0].kind == a or n.sons[0].kind == b:
       # addr ( deref ( x )) --> x