fixes a serious codegen bug that caused to emit wrong barriers in rare cases

This commit is contained in:
Araq 2015-04-19 13:36:22 +02:00
commit 89cbf092b2
3 changed files with 71 additions and 13 deletions

View file

@ -685,19 +685,23 @@ proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) =
else:
var a: TLoc
initLocExprSingleUse(p, e.sons[0], a)
let typ = skipTypes(a.t, abstractInst)
case typ.kind
of tyRef:
d.s = OnHeap
of tyVar:
d.s = OnUnknown
if tfVarIsPtr notin typ.flags and p.module.compileToCpp and
e.kind == nkHiddenDeref:
putIntoDest(p, d, e.typ, rdLoc(a))
return
of tyPtr:
d.s = OnUnknown # BUGFIX!
else: internalError(e.info, "genDeref " & $a.t.kind)
if d.k == locNone:
let typ = skipTypes(a.t, abstractInst)
# dest = *a; <-- We do not know that 'dest' is on the heap!
# It is completely wrong to set 'd.s' here, unless it's not yet
# been assigned to.
case typ.kind
of tyRef:
d.s = OnHeap
of tyVar:
d.s = OnUnknown
if tfVarIsPtr notin typ.flags and p.module.compileToCpp and
e.kind == nkHiddenDeref:
putIntoDest(p, d, e.typ, rdLoc(a))
return
of tyPtr:
d.s = OnUnknown # BUGFIX!
else: internalError(e.info, "genDeref " & $a.t.kind)
if enforceDeref and mt == ctPtrToArray:
# we lie about the type for better C interop: 'ptr array[3,T]' is
# translated to 'ptr T', but for deref'ing this produces wrong code.