enforce 'var T' produces a view into the first parameter; refs #7373

This commit is contained in:
Andreas Rumpf
2018-03-24 09:41:04 +01:00
parent 6f747674be
commit 3be4f9111c
2 changed files with 19 additions and 4 deletions

View File

@@ -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]

View File

@@ -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()