diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-03-24 09:41:04 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-03-24 09:41:04 +0100 |
commit | 3be4f9111cadd84c77a0b619850092743b154a1e (patch) | |
tree | 3f18cbce6e0daca7c5e08ad0f2a22f1af8727a21 | |
parent | 6f747674be8eacc6d0fbd62b5dcfdb75c939bcc1 (diff) | |
download | Nim-3be4f9111cadd84c77a0b619850092743b154a1e.tar.gz |
enforce 'var T' produces a view into the first parameter; refs #7373
-rw-r--r-- | compiler/semexprs.nim | 11 | ||||
-rw-r--r-- | tests/varres/twrong_parameter.nim | 12 |
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() |