summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ccgcalls.nim13
-rw-r--r--compiler/ccgexprs.nim1
-rw-r--r--compiler/ccgstmts.nim16
-rw-r--r--compiler/ccgtrav.nim2
-rw-r--r--compiler/cgen.nim4
-rw-r--r--lib/system/repr.nim4
-rw-r--r--tests/ccgbugs/tmissinginit.nim30
-rw-r--r--tests/misc/tstrange.nim3
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'''
 """