* fixes #11095
This commit is contained in:
Andreas Rumpf
2019-04-25 07:59:34 +02:00
committed by GitHub
parent a644f443bc
commit eb9043c0e9
3 changed files with 61 additions and 24 deletions

View File

@@ -567,19 +567,36 @@ proc genReturn(c: var Con; n: PNode) =
const
InterestingSyms = {skVar, skResult, skLet, skParam, skForVar, skTemp}
PathKinds* = {nkDotExpr, nkCheckedFieldExpr,
PathKinds0 = {nkDotExpr, nkCheckedFieldExpr,
nkBracketExpr, nkDerefExpr, nkHiddenDeref,
nkAddr, nkHiddenAddr,
nkHiddenStdConv, nkHiddenSubConv, nkObjDownConv, nkObjUpConv}
nkObjDownConv, nkObjUpConv}
PathKinds1 = {nkHiddenStdConv, nkHiddenSubConv}
proc getRoot(n: PNode): PNode =
result = n
while true:
case result.kind
of PathKinds0:
result = result[0]
of PathKinds1:
result = result[1]
else: break
proc skipConvDfa*(n: PNode): PNode =
result = n
while true:
case result.kind
of nkObjDownConv, nkObjUpConv:
result = result[0]
of PathKinds1:
result = result[1]
else: break
proc genUse(c: var Con; orig: PNode) =
var n = orig
var iters = 0
while n.kind in PathKinds:
n = n[0]
inc iters
let n = dfa.getRoot(orig)
if n.kind == nkSym and n.sym.kind in InterestingSyms:
c.code.add Instr(n: orig, kind: use, sym: if iters > 0: nil else: n.sym)
c.code.add Instr(n: orig, kind: use, sym: if orig != n: nil else: n.sym)
proc aliases(obj, field: PNode): bool =
var n = field
@@ -729,7 +746,7 @@ proc gen(c: var Con; n: PNode) =
# "uses" 'i'. But we are only talking about builtin array indexing so
# it doesn't matter and 'x = 34' is NOT a usage of 'x'.
genDef(c, n[0])
of PathKinds:
of PathKinds0 - {nkHiddenStdConv, nkHiddenSubConv, nkObjDownConv, nkObjUpConv}:
genUse(c, n)
of nkIfStmt, nkIfExpr: genIf(c, n)
of nkWhenStmt:
@@ -746,8 +763,8 @@ proc gen(c: var Con; n: PNode) =
nkBracket, nkCurly, nkPar, nkTupleConstr, nkClosure, nkObjConstr:
for x in n: gen(c, x)
of nkPragmaBlock: gen(c, n.lastSon)
of nkDiscardStmt: gen(c, n.sons[0])
of nkConv, nkExprColonExpr, nkExprEqExpr, nkCast:
of nkDiscardStmt, nkObjDownConv, nkObjUpConv: gen(c, n.sons[0])
of nkConv, nkExprColonExpr, nkExprEqExpr, nkCast, nkHiddenSubConv, nkHiddenStdConv:
gen(c, n.sons[1])
of nkStringToCString, nkCStringToString: gen(c, n.sons[0])
of nkVarSection, nkLetSection: genVarSection(c, n)

View File

@@ -195,15 +195,17 @@ proc isLastRead(n: PNode; c: var Con): bool =
# first we need to search for the instruction that belongs to 'n':
c.otherRead = nil
var instr = -1
let m = dfa.skipConvDfa(n)
for i in 0..<c.g.len:
# This comparison is correct and MUST not be ``instrTargets``:
if c.g[i].kind == use and c.g[i].n == n:
if c.g[i].kind == use and c.g[i].n == m:
if instr < 0:
instr = i
break
dbg:
echo "starting point for ", n, " is ", instr
echo "starting point for ", n, " is ", instr, " ", n.kind
if instr < 0: return false
# we go through all paths beginning from 'instr+1' and need to
@@ -625,7 +627,9 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
result = genCopy(c, dest.typ, dest, ri)
result.add p(ri, c)
of nkHiddenSubConv, nkHiddenStdConv:
if ri[1].kind in movableNodeKinds:
if sameType(ri.typ, ri[1].typ):
result = moveOrCopy(dest, ri[1], c)
elif ri[1].kind in movableNodeKinds:
result = moveOrCopy(dest, ri[1], c)
var b = newNodeIT(ri.kind, ri.info, ri.typ)
b.add ri[0] # add empty node

View File

@@ -2,30 +2,46 @@ discard """
output: '''works'''
"""
type
MyVal = object
f: ptr float
# bug #11095
proc `=destroy`(x: var MyVal) =
type
MyVal[T] = object
f: ptr T
proc `=destroy`[T](x: var MyVal[T]) =
if x.f != nil:
dealloc(x.f)
proc `=sink`(x1: var MyVal, x2: Myval) =
proc `=sink`[T](x1: var MyVal[T], x2: MyVal[T]) =
if x1.f != x2.f:
`=destroy`(x1)
x1.f = x2.f
proc `=`(x1: var MyVal, x2: Myval) {.error.}
proc `=`[T](x1: var MyVal[T], x2: MyVal[T]) {.error.}
proc newVal(x: float): MyVal =
result.f = create(float)
proc newVal[T](x: sink T): MyVal[T] =
result.f = create(T)
result.f[] = x
proc sinkMe(x: sink MyVal) =
proc set[T](x: var MyVal[T], val: T) =
x.f[] = val
proc sinkMe[T](x: sink MyVal[T]) =
discard
var flag = false
proc main =
var y = (newVal(3.0), newVal(4.0))
var y = case flag
of true:
var x1 = newVal[float](1.0)
var x2 = newVal[float](2.0)
(newVal(x1), newVal(x2))
of false:
var x1 = newVal[float](1.0)
var x2 = newVal[float](2.0)
(newVal(x1), newVal(x2))
sinkMe y[0]
sinkMe y[1]