diff options
author | LemonBoy <LemonBoy@users.noreply.github.com> | 2018-08-14 20:38:04 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-08-14 20:38:04 +0200 |
commit | c04404635b9efa2d6642887ca40f6222c54d9465 (patch) | |
tree | a00d4094e0085d021360c03e90aa0abd08b47f54 /compiler | |
parent | 9a7e6be62f6ee8818c6ef2f1504a6dd75774a616 (diff) | |
download | Nim-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.nim | 8 | ||||
-rw-r--r-- | compiler/astalgo.nim | 2 | ||||
-rw-r--r-- | compiler/transf.nim | 4 |
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 |