diff options
-rw-r--r-- | compiler/ccgcalls.nim | 13 | ||||
-rw-r--r-- | compiler/ccgexprs.nim | 1 | ||||
-rw-r--r-- | compiler/ccgstmts.nim | 16 | ||||
-rw-r--r-- | compiler/ccgtrav.nim | 2 | ||||
-rw-r--r-- | compiler/cgen.nim | 4 | ||||
-rw-r--r-- | lib/system/repr.nim | 4 | ||||
-rw-r--r-- | tests/ccgbugs/tmissinginit.nim | 30 | ||||
-rw-r--r-- | tests/misc/tstrange.nim | 3 |
8 files changed, 56 insertions, 17 deletions
diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index 71e23aa1d..adcc95e84 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -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) diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 3fe6140a3..b5817de05 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -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) diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index a8cfa57e4..f32ff3c78 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -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) diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim index 26f474659..a5bf9e7a7 100644 --- a/compiler/ccgtrav.nim +++ b/compiler/ccgtrav.nim @@ -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 diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 41f380d1b..51444e108 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -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: diff --git a/lib/system/repr.nim b/lib/system/repr.nim index d6df61fd3..8e1bc5f26 100644 --- a/lib/system/repr.nim +++ b/lib/system/repr.nim @@ -221,7 +221,7 @@ when not defined(useNimRtl): dec(cl.recdepth) case typ.kind of tySet: reprSetAux(result, p, typ) - of tyArray: reprArray(result, p, typ, cl) + of tyArray, tyArrayConstr: reprArray(result, p, typ, cl) of tyTuple: reprRecord(result, p, typ, cl) of tyObject: var t = cast[ptr PNimType](p)[] @@ -275,7 +275,7 @@ when not defined(useNimRtl): cl: TReprClosure initReprClosure(cl) result = "" - if typ.kind in {tyObject, tyTuple, tyArray, tySet}: + if typ.kind in {tyObject, tyTuple, tyArray, tyArrayConstr, tySet}: reprAux(result, p, typ, cl) else: var p = p diff --git a/tests/ccgbugs/tmissinginit.nim b/tests/ccgbugs/tmissinginit.nim new file mode 100644 index 000000000..36648ef8d --- /dev/null +++ b/tests/ccgbugs/tmissinginit.nim @@ -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() diff --git a/tests/misc/tstrange.nim b/tests/misc/tstrange.nim index 6bafcabdc..8742011bb 100644 --- a/tests/misc/tstrange.nim +++ b/tests/misc/tstrange.nim @@ -1,7 +1,6 @@ discard """ file: "tstrange.nim" - output: '''hallo4 -0 + output: '''hallo40 1 2''' """ |