From 3be4f9111cadd84c77a0b619850092743b154a1e Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Sat, 24 Mar 2018 09:41:04 +0100 Subject: [PATCH] enforce 'var T' produces a view into the first parameter; refs #7373 --- compiler/semexprs.nim | 11 +++++++---- tests/varres/twrong_parameter.nim | 12 ++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 tests/varres/twrong_parameter.nim 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()