fixes #668
This commit is contained in:
parent
196977f623
commit
a5e4d2f7a3
3 changed files with 51 additions and 5 deletions
|
|
@ -179,5 +179,11 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
|
||||||
result = isPartOf(a[0], b)
|
result = isPartOf(a[0], b)
|
||||||
if result == arNo: result = arMaybe
|
if result == arNo: result = arMaybe
|
||||||
else: discard
|
else: discard
|
||||||
|
of nkObjConstr:
|
||||||
|
result = arNo
|
||||||
|
for i in 1..<b.len:
|
||||||
|
let res = isPartOf(a, b[i][1])
|
||||||
|
if res != arNo:
|
||||||
|
result = res
|
||||||
|
if res == arYes: break
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1236,18 +1236,32 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
else:
|
else:
|
||||||
genAssignment(p, d, tmp, {})
|
genAssignment(p, d, tmp, {})
|
||||||
|
|
||||||
|
proc lhsDoesAlias(a, b: PNode): bool =
|
||||||
|
for y in b:
|
||||||
|
if isPartOf(a, y) != arNo: return true
|
||||||
|
|
||||||
proc genSeqConstr(p: BProc, n: PNode, d: var TLoc) =
|
proc genSeqConstr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
var arr: TLoc
|
var arr, tmp: TLoc
|
||||||
if d.k == locNone:
|
# bug #668
|
||||||
|
let doesAlias = lhsDoesAlias(d.lode, n)
|
||||||
|
let dest = if doesAlias: addr(tmp) else: addr(d)
|
||||||
|
if doesAlias:
|
||||||
|
getTemp(p, n.typ, tmp)
|
||||||
|
elif d.k == locNone:
|
||||||
getTemp(p, n.typ, d)
|
getTemp(p, n.typ, d)
|
||||||
# generate call to newSeq before adding the elements per hand:
|
# generate call to newSeq before adding the elements per hand:
|
||||||
genNewSeqAux(p, d, intLiteral(sonsLen(n)))
|
genNewSeqAux(p, dest[], intLiteral(sonsLen(n)))
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
initLoc(arr, locExpr, n[i], OnHeap)
|
initLoc(arr, locExpr, n[i], OnHeap)
|
||||||
arr.r = rfmt(nil, "$1->data[$2]", rdLoc(d), intLiteral(i))
|
arr.r = rfmt(nil, "$1->data[$2]", rdLoc(dest[]), intLiteral(i))
|
||||||
arr.storage = OnHeap # we know that sequences are on the heap
|
arr.storage = OnHeap # we know that sequences are on the heap
|
||||||
expr(p, n[i], arr)
|
expr(p, n[i], arr)
|
||||||
gcUsage(n)
|
gcUsage(n)
|
||||||
|
if doesAlias:
|
||||||
|
if d.k == locNone:
|
||||||
|
d = tmp
|
||||||
|
else:
|
||||||
|
genAssignment(p, d, tmp, {})
|
||||||
|
|
||||||
proc genArrToSeq(p: BProc, n: PNode, d: var TLoc) =
|
proc genArrToSeq(p: BProc, n: PNode, d: var TLoc) =
|
||||||
var elem, a, arr: TLoc
|
var elem, a, arr: TLoc
|
||||||
|
|
|
||||||
26
tests/ccgbugs/tobjconstr_bad_aliasing.nim
Normal file
26
tests/ccgbugs/tobjconstr_bad_aliasing.nim
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
discard """
|
||||||
|
output: '''(10, (20, ))'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
import strutils, sequtils
|
||||||
|
|
||||||
|
# bug #668
|
||||||
|
|
||||||
|
type
|
||||||
|
TThing = ref object
|
||||||
|
data: int
|
||||||
|
children: seq[TThing]
|
||||||
|
|
||||||
|
proc `$`(t: TThing): string =
|
||||||
|
result = "($1, $2)" % @[$t.data, join(map(t.children, proc(th: TThing): string = $th), ", ")]
|
||||||
|
|
||||||
|
proc somethingelse(): seq[TThing] =
|
||||||
|
result = @[TThing(data: 20, children: @[])]
|
||||||
|
|
||||||
|
proc dosomething(): seq[TThing] =
|
||||||
|
result = somethingelse()
|
||||||
|
|
||||||
|
result = @[TThing(data: 10, children: result)]
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
echo($dosomething()[0])
|
||||||
Loading…
Add table
Add a link
Reference in a new issue