diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2019-04-25 07:59:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-25 07:59:34 +0200 |
commit | eb9043c0e9f835cb42b83d3a954058cdde01a72b (patch) | |
tree | dcf2b20ce7f3e63e58a4493be5057a16d86d088e /compiler | |
parent | a644f443bcd2d969cbd2349d25f992309526373d (diff) | |
download | Nim-eb9043c0e9f835cb42b83d3a954058cdde01a72b.tar.gz |
fixes #11095 (#11104)
* fixes #11095
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/dfa.nim | 39 | ||||
-rw-r--r-- | compiler/injectdestructors.nim | 10 |
2 files changed, 35 insertions, 14 deletions
diff --git a/compiler/dfa.nim b/compiler/dfa.nim index 0072c9410..45e1aaffe 100644 --- a/compiler/dfa.nim +++ b/compiler/dfa.nim @@ -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) diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 4bcc38cb3..5958d89ae 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -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 |