more precise analysis about 'observable stores' [backport:1.2] (#14582)

This commit is contained in:
Andreas Rumpf 2020-06-06 21:28:46 +02:00 • committed by GitHub
commit 32083c7ff8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 15 additions and 4 deletions

View file

@ -22,14 +22,20 @@ proc canRaiseDisp(p: BProc; n: PNode): bool =
result = canRaiseConservative(n)
proc preventNrvo(p: BProc; le, ri: PNode): bool =
proc locationEscapes(p: BProc; le: PNode): bool =
proc locationEscapes(p: BProc; le: PNode; inTryStmt: bool): bool =
var n = le
while true:
# do NOT follow nkHiddenDeref here!
case n.kind
of nkSym:
# we don't own the location so it escapes:
return n.sym.owner != p.prc
if n.sym.owner != p.prc:
return true
elif inTryStmt and sfUsedInFinallyOrExcept in n.sym.flags:
# it is also an observable store if the location is used
# in 'except' or 'finally'
return true
return false
of nkDotExpr, nkBracketExpr, nkObjUpConv, nkObjDownConv,
nkCheckedFieldExpr:
n = n[0]
@ -46,7 +52,7 @@ proc preventNrvo(p: BProc; le, ri: PNode): bool =
# we use the weaker 'canRaise' here in order to prevent too many
# annoying warnings, see #14514
if canRaise(ri[0]) and
(p.nestedTryStmts.len > 0 or locationEscapes(p, le)):
locationEscapes(p, le, p.nestedTryStmts.len > 0):
message(p.config, le.info, warnObservableStores, $le)
proc hasNoInit(call: PNode): bool {.inline.} =