summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorLemonBoy <LemonBoy@users.noreply.github.com>2019-02-06 21:26:55 +0100
committerAndreas Rumpf <rumpf_a@web.de>2019-02-06 21:26:55 +0100
commit294b2e03b2def1fe5a14e7116af412dc761c81f9 (patch)
tree2fe8515ddd33d63a8487d0efe2640ca934202965
parent0036014727a90886e47c658e72e0936c2193fdbb (diff)
downloadNim-294b2e03b2def1fe5a14e7116af412dc761c81f9.tar.gz
Reject assignments with nkEmpty RHS (#9000)
Fixes #8997
-rw-r--r--compiler/semexprs.nim16
-rw-r--r--tests/macros/t8997.nim26
2 files changed, 35 insertions, 7 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 68f1c6c3a..1b8a978ec 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -39,13 +39,14 @@ proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
 
 proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
 
+template rejectEmptyNode(n: PNode) =
+  # No matter what a nkEmpty node is not what we want here
+  if n.kind == nkEmpty: illFormedAst(n, c.config)
+
 proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
+  rejectEmptyNode(n)
   # same as 'semExprWithType' but doesn't check for proc vars
   result = semExpr(c, n, flags + {efOperand})
-  #if result.kind == nkEmpty and result.typ.isNil:
-    # do not produce another redundant error message:
-    #raiseRecoverableError("")
-  #  result = errorNode(c, n)
   if result.typ != nil:
     # XXX tyGenericInst here?
     if result.typ.kind == tyProc and tfUnresolved in result.typ.flags:
@@ -59,10 +60,10 @@ proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
     result.typ = errorType(c)
 
 proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
+  rejectEmptyNode(n)
   result = semExpr(c, n, flags+{efWantValue})
-  if result.isNil or result.kind == nkEmpty:
+  if result.kind == nkEmpty:
     # do not produce another redundant error message:
-    #raiseRecoverableError("")
     result = errorNode(c, n)
   if result.typ == nil or result.typ == c.enforceVoidContext:
     localError(c.config, n.info, errExprXHasNoType %
@@ -72,7 +73,8 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
     if result.typ.kind in {tyVar, tyLent}: result = newDeref(result)
 
 proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
-  result = semExpr(c, n, flags)
+  rejectEmptyNode(n)
+  result = semExpr(c, n, flags+{efWantValue})
   if result.kind == nkEmpty:
     # do not produce another redundant error message:
     result = errorNode(c, n)
diff --git a/tests/macros/t8997.nim b/tests/macros/t8997.nim
new file mode 100644
index 000000000..af04fb127
--- /dev/null
+++ b/tests/macros/t8997.nim
@@ -0,0 +1,26 @@
+discard """
+  line: 24
+  errormsg: "illformed AST: "
+"""
+
+import macros
+
+type
+  Node* = ref object
+    children: seq[Node]
+
+proc newNode*(): Node =
+  Node(children: newSeq[Node]())
+
+macro build*(body: untyped): untyped =
+
+  template appendElement(tmp, childrenBlock) {.dirty.} =
+    bind newNode
+    let tmp = newNode()
+    tmp.children = childrenBlock  # this line seems to be the problem
+
+  let tmp = genSym(nskLet, "tmp")
+  let childrenBlock = newEmptyNode()
+  result = getAst(appendElement(tmp, childrenBlock))
+
+build(body)