summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorBung <crc32@qq.com>2022-12-11 13:58:29 +0800
committerGitHub <noreply@github.com>2022-12-11 06:58:29 +0100
commit1585bfec3bf6d6ad59f2bcbc82be2b2ba87f7313 (patch)
tree255060ab6ad03384fd6214c53b32f29864e482a5
parent07be1791ba52d03dd2026c14ca34e5acc6ef9213 (diff)
downloadNim-1585bfec3bf6d6ad59f2bcbc82be2b2ba87f7313.tar.gz
fix #16758 Nim crashes in fixAbstractType (#20855)
* fix #16758 Nim crashes in fixAbstractType

* Update compiler/semexprs.nim

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
-rw-r--r--compiler/semexprs.nim3
-rw-r--r--tests/macros/t16758.nim38
2 files changed, 41 insertions, 0 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 22a247ceb..064eae0b7 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -693,6 +693,9 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PTyp
 proc fixAbstractType(c: PContext, n: PNode) =
   for i in 1..<n.len:
     let it = n[i]
+    if it == nil:
+      localError(c.config, n.info, "'$1' has nil child at index $2" % [renderTree(n, {renderNoComments}), $i])
+      return
     # do not get rid of nkHiddenSubConv for OpenArrays, the codegen needs it:
     if it.kind == nkHiddenSubConv and
         skipTypes(it.typ, abstractVar).kind notin {tyOpenArray, tyVarargs}:
diff --git a/tests/macros/t16758.nim b/tests/macros/t16758.nim
new file mode 100644
index 000000000..66b6d42c5
--- /dev/null
+++ b/tests/macros/t16758.nim
@@ -0,0 +1,38 @@
+discard """

+errormsg: "'blk.p(a)' has nil child at index 1"

+action: reject

+"""

+import macros

+

+type BlockLiteral[T] = object

+  p: T

+

+proc p[T](a:int) = echo 1

+proc p[T](a:string) = echo "a"

+

+iterator arguments(formalParams: NimNode): NimNode =

+  var iParam = 0

+  for i in 1 ..< formalParams.len:

+    let pp = formalParams[i]

+    for j in 0 .. pp.len - 3:

+      yield pp[j]

+      inc iParam

+

+macro implementInvoke(T: typedesc): untyped =

+  let t = getTypeImpl(T)[1]

+

+  let call = newCall(newDotExpr(ident"blk", ident"p"))

+  let params = copyNimTree(t[0])

+  result = newProc(ident"invoke", body = call)

+  # result[2] = newTree(nnkGenericParams,T)

+  for n in arguments(params):

+    call.add(n)

+  

+  params.insert(1, newIdentDefs(ident"blk", newTree(nnkBracketExpr, bindSym"BlockLiteral", T)))

+  result.params = params

+

+proc getInvoke(T: typedesc) =

+  implementInvoke(T)

+

+

+getInvoke(proc(a: int))