mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-18 17:08:32 +00:00
fixes #1434
This commit is contained in:
@@ -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:
|
||||
if d.k in {locTemp, locNone} or not leftAppearsOnRightSide(le, ri):
|
||||
# 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):
|
||||
# reset before pass as 'result' var:
|
||||
resetLoc(p, d)
|
||||
@@ -38,7 +38,7 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc,
|
||||
line(p, cpsStmts, pl)
|
||||
else:
|
||||
var tmp: TLoc
|
||||
getTemp(p, typ.sons[0], tmp)
|
||||
getTemp(p, typ.sons[0], tmp, needsInit=true)
|
||||
app(pl, addrLoc(tmp))
|
||||
app(pl, ~");$n")
|
||||
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:
|
||||
if d.k in {locTemp, locNone} or not leftAppearsOnRightSide(le, ri):
|
||||
# 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):
|
||||
# reset before pass as 'result' var:
|
||||
resetLoc(p, d)
|
||||
@@ -203,7 +204,7 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
|
||||
genCallPattern()
|
||||
else:
|
||||
var tmp: TLoc
|
||||
getTemp(p, typ.sons[0], tmp)
|
||||
getTemp(p, typ.sons[0], tmp, needsInit=true)
|
||||
app(pl, addrLoc(tmp))
|
||||
genCallPattern()
|
||||
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:
|
||||
if d.k in {locTemp, locNone}:
|
||||
# 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, addrLoc(d))
|
||||
app(pl, ~"];$n")
|
||||
line(p, cpsStmts, pl)
|
||||
else:
|
||||
var tmp: TLoc
|
||||
getTemp(p, typ.sons[0], tmp)
|
||||
getTemp(p, typ.sons[0], tmp, needsInit=true)
|
||||
app(pl, addrLoc(tmp))
|
||||
app(pl, ~"];$n")
|
||||
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)
|
||||
|
||||
proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
||||
# XXX we don't generate keep alive info for now here
|
||||
var a: TLoc
|
||||
initLocExpr(p, e.sons[1], a)
|
||||
var t = skipTypes(e.sons[1].typ, abstractVarRange)
|
||||
|
||||
@@ -24,6 +24,15 @@ proc registerGcRoot(p: BProc, v: PSym) =
|
||||
linefmt(p.module.initProc, cpsStmts,
|
||||
"#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) =
|
||||
var tup, field: TLoc
|
||||
if n.kind != nkVarTuple: internalError(n.info, "genVarTuple")
|
||||
@@ -40,7 +49,7 @@ proc genVarTuple(p: BProc, n: PNode) =
|
||||
registerGcRoot(p, v)
|
||||
else:
|
||||
assignLocalVar(p, v)
|
||||
initLocalVar(p, v, immediateAsgn=true)
|
||||
initLocalVar(p, v, immediateAsgn=isAssignedImmediately(n[L-1]))
|
||||
initLoc(field, locExpr, t.sons[i], tup.s)
|
||||
if t.kind == tyTuple:
|
||||
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)])
|
||||
|
||||
proc genVarPrototypeAux(m: BModule, sym: PSym)
|
||||
|
||||
proc genSingleVar(p: BProc, a: PNode) =
|
||||
var v = a.sons[0].sym
|
||||
if sfCompileTime in v.flags: return
|
||||
var targetProc = p
|
||||
var immediateAsgn = a.sons[2].kind != nkEmpty
|
||||
var immediateAsgn = isAssignedImmediately(a.sons[2])
|
||||
if sfGlobal in v.flags:
|
||||
if sfPure in v.flags:
|
||||
# v.owner.kind != skModule:
|
||||
@@ -177,7 +187,7 @@ proc genSingleVar(p: BProc, a: PNode) =
|
||||
loadInto(targetProc, a.sons[0], a.sons[2], v.loc)
|
||||
|
||||
proc genClosureVar(p: BProc, a: PNode) =
|
||||
var immediateAsgn = a.sons[2].kind != nkEmpty
|
||||
var immediateAsgn = isAssignedImmediately(a.sons[2])
|
||||
if immediateAsgn:
|
||||
var v: TLoc
|
||||
initLocExpr(p, a.sons[0], v)
|
||||
|
||||
@@ -19,7 +19,7 @@ type
|
||||
|
||||
proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType)
|
||||
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) =
|
||||
if n == nil: return
|
||||
|
||||
@@ -399,7 +399,7 @@ proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) =
|
||||
if not immediateAsgn:
|
||||
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)
|
||||
if gCmd == cmdCompileToLLVM:
|
||||
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.s = OnStack
|
||||
result.flags = {}
|
||||
constructLoc(p, result, isTemp=true)
|
||||
constructLoc(p, result, not needsInit)
|
||||
|
||||
proc keepAlive(p: BProc, toKeepAlive: TLoc) =
|
||||
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 """
|
||||
file: "tstrange.nim"
|
||||
output: '''hallo4
|
||||
0
|
||||
output: '''hallo40
|
||||
1
|
||||
2'''
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user