mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-03 11:42:33 +00:00
fixes #668
This commit is contained in:
@@ -179,5 +179,11 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
|
||||
result = isPartOf(a[0], b)
|
||||
if result == arNo: result = arMaybe
|
||||
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
|
||||
|
||||
|
||||
@@ -1236,18 +1236,32 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||
else:
|
||||
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) =
|
||||
var arr: TLoc
|
||||
if d.k == locNone:
|
||||
var arr, tmp: TLoc
|
||||
# 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)
|
||||
# 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):
|
||||
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
|
||||
expr(p, n[i], arr)
|
||||
gcUsage(n)
|
||||
if doesAlias:
|
||||
if d.k == locNone:
|
||||
d = tmp
|
||||
else:
|
||||
genAssignment(p, d, tmp, {})
|
||||
|
||||
proc genArrToSeq(p: BProc, n: PNode, d: var 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])
|
||||
Reference in New Issue
Block a user