fixes #1434
This commit is contained in:
parent
af0de9090e
commit
f3d530e482
7 changed files with 54 additions and 15 deletions
|
|
@ -29,7 +29,7 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc,
|
||||||
# beware of 'result = p(result)'. We may need to allocate a temporary:
|
# beware of 'result = p(result)'. We may need to allocate a temporary:
|
||||||
if d.k in {locTemp, locNone} or not leftAppearsOnRightSide(le, ri):
|
if d.k in {locTemp, locNone} or not leftAppearsOnRightSide(le, ri):
|
||||||
# Great, we can use 'd':
|
# Great, we can use 'd':
|
||||||
if d.k == locNone: getTemp(p, typ.sons[0], d)
|
if d.k == locNone: getTemp(p, typ.sons[0], d, needsInit=true)
|
||||||
elif d.k notin {locExpr, locTemp} and not hasNoInit(ri):
|
elif d.k notin {locExpr, locTemp} and not hasNoInit(ri):
|
||||||
# reset before pass as 'result' var:
|
# reset before pass as 'result' var:
|
||||||
resetLoc(p, d)
|
resetLoc(p, d)
|
||||||
|
|
@ -38,7 +38,7 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc,
|
||||||
line(p, cpsStmts, pl)
|
line(p, cpsStmts, pl)
|
||||||
else:
|
else:
|
||||||
var tmp: TLoc
|
var tmp: TLoc
|
||||||
getTemp(p, typ.sons[0], tmp)
|
getTemp(p, typ.sons[0], tmp, needsInit=true)
|
||||||
app(pl, addrLoc(tmp))
|
app(pl, addrLoc(tmp))
|
||||||
app(pl, ~");$n")
|
app(pl, ~");$n")
|
||||||
line(p, cpsStmts, pl)
|
line(p, cpsStmts, pl)
|
||||||
|
|
@ -195,7 +195,8 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
|
||||||
# beware of 'result = p(result)'. We may need to allocate a temporary:
|
# beware of 'result = p(result)'. We may need to allocate a temporary:
|
||||||
if d.k in {locTemp, locNone} or not leftAppearsOnRightSide(le, ri):
|
if d.k in {locTemp, locNone} or not leftAppearsOnRightSide(le, ri):
|
||||||
# Great, we can use 'd':
|
# Great, we can use 'd':
|
||||||
if d.k == locNone: getTemp(p, typ.sons[0], d)
|
if d.k == locNone:
|
||||||
|
getTemp(p, typ.sons[0], d, needsInit=true)
|
||||||
elif d.k notin {locExpr, locTemp} and not hasNoInit(ri):
|
elif d.k notin {locExpr, locTemp} and not hasNoInit(ri):
|
||||||
# reset before pass as 'result' var:
|
# reset before pass as 'result' var:
|
||||||
resetLoc(p, d)
|
resetLoc(p, d)
|
||||||
|
|
@ -203,7 +204,7 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
|
||||||
genCallPattern()
|
genCallPattern()
|
||||||
else:
|
else:
|
||||||
var tmp: TLoc
|
var tmp: TLoc
|
||||||
getTemp(p, typ.sons[0], tmp)
|
getTemp(p, typ.sons[0], tmp, needsInit=true)
|
||||||
app(pl, addrLoc(tmp))
|
app(pl, addrLoc(tmp))
|
||||||
genCallPattern()
|
genCallPattern()
|
||||||
genAssignment(p, d, tmp, {}) # no need for deep copying
|
genAssignment(p, d, tmp, {}) # no need for deep copying
|
||||||
|
|
@ -278,14 +279,14 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
|
||||||
# beware of 'result = p(result)'. We always allocate a temporary:
|
# beware of 'result = p(result)'. We always allocate a temporary:
|
||||||
if d.k in {locTemp, locNone}:
|
if d.k in {locTemp, locNone}:
|
||||||
# We already got a temp. Great, special case it:
|
# We already got a temp. Great, special case it:
|
||||||
if d.k == locNone: getTemp(p, typ.sons[0], d)
|
if d.k == locNone: getTemp(p, typ.sons[0], d, needsInit=true)
|
||||||
app(pl, ~"Result: ")
|
app(pl, ~"Result: ")
|
||||||
app(pl, addrLoc(d))
|
app(pl, addrLoc(d))
|
||||||
app(pl, ~"];$n")
|
app(pl, ~"];$n")
|
||||||
line(p, cpsStmts, pl)
|
line(p, cpsStmts, pl)
|
||||||
else:
|
else:
|
||||||
var tmp: TLoc
|
var tmp: TLoc
|
||||||
getTemp(p, typ.sons[0], tmp)
|
getTemp(p, typ.sons[0], tmp, needsInit=true)
|
||||||
app(pl, addrLoc(tmp))
|
app(pl, addrLoc(tmp))
|
||||||
app(pl, ~"];$n")
|
app(pl, ~"];$n")
|
||||||
line(p, cpsStmts, pl)
|
line(p, cpsStmts, pl)
|
||||||
|
|
|
||||||
|
|
@ -1217,7 +1217,6 @@ proc genOf(p: BProc, n: PNode, d: var TLoc) =
|
||||||
genOf(p, n.sons[1], n.sons[2].typ, d)
|
genOf(p, n.sons[1], n.sons[2].typ, d)
|
||||||
|
|
||||||
proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
# XXX we don't generate keep alive info for now here
|
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, e.sons[1], a)
|
initLocExpr(p, e.sons[1], a)
|
||||||
var t = skipTypes(e.sons[1].typ, abstractVarRange)
|
var t = skipTypes(e.sons[1].typ, abstractVarRange)
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,15 @@ proc registerGcRoot(p: BProc, v: PSym) =
|
||||||
linefmt(p.module.initProc, cpsStmts,
|
linefmt(p.module.initProc, cpsStmts,
|
||||||
"#nimRegisterGlobalMarker($1);$n", prc)
|
"#nimRegisterGlobalMarker($1);$n", prc)
|
||||||
|
|
||||||
|
proc isAssignedImmediately(n: PNode): bool {.inline.} =
|
||||||
|
if n.kind == nkEmpty: return false
|
||||||
|
if isInvalidReturnType(n.typ):
|
||||||
|
# var v = f()
|
||||||
|
# is transformed into: var v; f(addr v)
|
||||||
|
# where 'f' **does not** initialize the result!
|
||||||
|
return false
|
||||||
|
result = true
|
||||||
|
|
||||||
proc genVarTuple(p: BProc, n: PNode) =
|
proc genVarTuple(p: BProc, n: PNode) =
|
||||||
var tup, field: TLoc
|
var tup, field: TLoc
|
||||||
if n.kind != nkVarTuple: internalError(n.info, "genVarTuple")
|
if n.kind != nkVarTuple: internalError(n.info, "genVarTuple")
|
||||||
|
|
@ -40,7 +49,7 @@ proc genVarTuple(p: BProc, n: PNode) =
|
||||||
registerGcRoot(p, v)
|
registerGcRoot(p, v)
|
||||||
else:
|
else:
|
||||||
assignLocalVar(p, v)
|
assignLocalVar(p, v)
|
||||||
initLocalVar(p, v, immediateAsgn=true)
|
initLocalVar(p, v, immediateAsgn=isAssignedImmediately(n[L-1]))
|
||||||
initLoc(field, locExpr, t.sons[i], tup.s)
|
initLoc(field, locExpr, t.sons[i], tup.s)
|
||||||
if t.kind == tyTuple:
|
if t.kind == tyTuple:
|
||||||
field.r = ropef("$1.Field$2", [rdLoc(tup), toRope(i)])
|
field.r = ropef("$1.Field$2", [rdLoc(tup), toRope(i)])
|
||||||
|
|
@ -146,11 +155,12 @@ proc genBreakState(p: BProc, n: PNode) =
|
||||||
# lineF(p, cpsStmts, "if (($1) < 0) break;$n", [rdLoc(a)])
|
# lineF(p, cpsStmts, "if (($1) < 0) break;$n", [rdLoc(a)])
|
||||||
|
|
||||||
proc genVarPrototypeAux(m: BModule, sym: PSym)
|
proc genVarPrototypeAux(m: BModule, sym: PSym)
|
||||||
|
|
||||||
proc genSingleVar(p: BProc, a: PNode) =
|
proc genSingleVar(p: BProc, a: PNode) =
|
||||||
var v = a.sons[0].sym
|
var v = a.sons[0].sym
|
||||||
if sfCompileTime in v.flags: return
|
if sfCompileTime in v.flags: return
|
||||||
var targetProc = p
|
var targetProc = p
|
||||||
var immediateAsgn = a.sons[2].kind != nkEmpty
|
var immediateAsgn = isAssignedImmediately(a.sons[2])
|
||||||
if sfGlobal in v.flags:
|
if sfGlobal in v.flags:
|
||||||
if sfPure in v.flags:
|
if sfPure in v.flags:
|
||||||
# v.owner.kind != skModule:
|
# v.owner.kind != skModule:
|
||||||
|
|
@ -177,7 +187,7 @@ proc genSingleVar(p: BProc, a: PNode) =
|
||||||
loadInto(targetProc, a.sons[0], a.sons[2], v.loc)
|
loadInto(targetProc, a.sons[0], a.sons[2], v.loc)
|
||||||
|
|
||||||
proc genClosureVar(p: BProc, a: PNode) =
|
proc genClosureVar(p: BProc, a: PNode) =
|
||||||
var immediateAsgn = a.sons[2].kind != nkEmpty
|
var immediateAsgn = isAssignedImmediately(a.sons[2])
|
||||||
if immediateAsgn:
|
if immediateAsgn:
|
||||||
var v: TLoc
|
var v: TLoc
|
||||||
initLocExpr(p, a.sons[0], v)
|
initLocExpr(p, a.sons[0], v)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ type
|
||||||
|
|
||||||
proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType)
|
proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType)
|
||||||
proc genCaseRange(p: BProc, branch: PNode)
|
proc genCaseRange(p: BProc, branch: PNode)
|
||||||
proc getTemp(p: BProc, t: PType, result: var TLoc)
|
proc getTemp(p: BProc, t: PType, result: var TLoc; needsInit=false)
|
||||||
|
|
||||||
proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, n: PNode) =
|
proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, n: PNode) =
|
||||||
if n == nil: return
|
if n == nil: return
|
||||||
|
|
|
||||||
|
|
@ -399,7 +399,7 @@ proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) =
|
||||||
if not immediateAsgn:
|
if not immediateAsgn:
|
||||||
constructLoc(p, v.loc)
|
constructLoc(p, v.loc)
|
||||||
|
|
||||||
proc getTemp(p: BProc, t: PType, result: var TLoc) =
|
proc getTemp(p: BProc, t: PType, result: var TLoc; needsInit=false) =
|
||||||
inc(p.labels)
|
inc(p.labels)
|
||||||
if gCmd == cmdCompileToLLVM:
|
if gCmd == cmdCompileToLLVM:
|
||||||
result.r = con("%LOC", toRope(p.labels))
|
result.r = con("%LOC", toRope(p.labels))
|
||||||
|
|
@ -411,7 +411,7 @@ proc getTemp(p: BProc, t: PType, result: var TLoc) =
|
||||||
result.t = getUniqueType(t)
|
result.t = getUniqueType(t)
|
||||||
result.s = OnStack
|
result.s = OnStack
|
||||||
result.flags = {}
|
result.flags = {}
|
||||||
constructLoc(p, result, isTemp=true)
|
constructLoc(p, result, not needsInit)
|
||||||
|
|
||||||
proc keepAlive(p: BProc, toKeepAlive: TLoc) =
|
proc keepAlive(p: BProc, toKeepAlive: TLoc) =
|
||||||
when false:
|
when false:
|
||||||
|
|
|
||||||
30
tests/ccgbugs/tmissinginit.nim
Normal file
30
tests/ccgbugs/tmissinginit.nim
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
discard """
|
||||||
|
output: '''0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
[[a = nil,
|
||||||
|
b = nil]]
|
||||||
|
"""
|
||||||
|
|
||||||
|
# bug #1475
|
||||||
|
type
|
||||||
|
Crash = object
|
||||||
|
a: string
|
||||||
|
b: seq[string]
|
||||||
|
|
||||||
|
proc initCrash(): Crash = discard
|
||||||
|
|
||||||
|
proc test() =
|
||||||
|
var blongname = [initCrash()]
|
||||||
|
echo repr(blongname)
|
||||||
|
|
||||||
|
# bug #1434
|
||||||
|
proc bug: array[1, int] = discard
|
||||||
|
|
||||||
|
echo bug()[0]
|
||||||
|
echo bug()[0]
|
||||||
|
echo bug()[0]
|
||||||
|
echo bug()[0]
|
||||||
|
|
||||||
|
when isMainModule: test()
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
discard """
|
discard """
|
||||||
file: "tstrange.nim"
|
file: "tstrange.nim"
|
||||||
output: '''hallo4
|
output: '''hallo40
|
||||||
0
|
|
||||||
1
|
1
|
||||||
2'''
|
2'''
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue