summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2018-03-24 09:41:04 +0100
committerAndreas Rumpf <rumpf_a@web.de>2018-03-24 09:41:04 +0100
commit3be4f9111cadd84c77a0b619850092743b154a1e (patch)
tree3f18cbce6e0daca7c5e08ad0f2a22f1af8727a21
parent6f747674be8eacc6d0fbd62b5dcfdb75c939bcc1 (diff)
downloadNim-3be4f9111cadd84c77a0b619850092743b154a1e.tar.gz
enforce 'var T' produces a view into the first parameter; refs #7373
-rw-r--r--compiler/semexprs.nim11
-rw-r--r--tests/varres/twrong_parameter.nim12
2 files changed, 19 insertions, 4 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index f6226ad77..7e7c496e3 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1304,10 +1304,13 @@ proc takeImplicitAddr(c: PContext, n: PNode; isLent: bool): PNode =
   # See RFC #7373, calls returning 'var T' are assumed to
   # return a view into the first argument (if there is one):
   let root = exprRoot(n)
-  if root != nil and root.owner == c.p.owner and
-      root.kind in {skLet, skVar, skTemp} and sfGlobal notin root.flags:
-    localError(n.info, "'$1' escapes its stack frame; context: '$2'" % [
-      root.name.s, renderTree(n, {renderNoComments})])
+  if root != nil and root.owner == c.p.owner:
+    if root.kind in {skLet, skVar, skTemp} and sfGlobal notin root.flags:
+      localError(n.info, "'$1' escapes its stack frame; context: '$2'" % [
+        root.name.s, renderTree(n, {renderNoComments})])
+    elif root.kind == skParam and root.position != 0:
+      localError(n.info, "'$1' is not the first parameter; context: '$2'" % [
+        root.name.s, renderTree(n, {renderNoComments})])
   case n.kind
   of nkHiddenAddr, nkAddr: return n
   of nkHiddenDeref, nkDerefExpr: return n.sons[0]
diff --git a/tests/varres/twrong_parameter.nim b/tests/varres/twrong_parameter.nim
new file mode 100644
index 000000000..34b0c7464
--- /dev/null
+++ b/tests/varres/twrong_parameter.nim
@@ -0,0 +1,12 @@
+discard """
+  line: 6
+  errormsg: "'x' is not the first parameter; context: 'x'"
+"""
+
+proc forward(abc: int; x: var int): var int = result = x
+
+proc foo(): var int =
+  var y = 9
+  result = forward(45, y)
+
+echo foo()