diff options
-rw-r--r-- | compiler/ccgexprs.nim | 10 | ||||
-rw-r--r-- | tests/ccgbugs/tassign_nil_strings.nim | 13 |
2 files changed, 20 insertions, 3 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 56ecf5ba3..d9e0ec479 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -151,7 +151,7 @@ proc getStorageLoc(n: PNode): TStorageLoc = result = getStorageLoc(n.sons[0]) else: result = OnUnknown -proc canMove(n: PNode): bool = +proc canMove(p: BProc, n: PNode): bool = # for now we're conservative here: if n.kind == nkBracket: # This needs to be kept consistent with 'const' seq code @@ -159,6 +159,10 @@ proc canMove(n: PNode): bool = if not isDeepConstExpr(n) or n.len == 0: if skipTypes(n.typ, abstractVarRange).kind == tySequence: return true + elif optNilSeqs notin p.options and + n.kind in nkStrKinds and n.strVal.len == 0: + # Empty strings are codegen'd as NIM_NIL so it's just a pointer copy + return true result = n.kind in nkCallKinds #if result: # echo n.info, " optimized ", n @@ -286,7 +290,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = of tySequence: if p.config.selectedGC == gcDestructors: genGenericAsgn(p, dest, src, flags) - elif (needToCopy notin flags and src.storage != OnStatic) or canMove(src.lode): + elif (needToCopy notin flags and src.storage != OnStatic) or canMove(p, src.lode): genRefAssign(p, dest, src, flags) else: linefmt(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n", @@ -295,7 +299,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = of tyString: if p.config.selectedGC == gcDestructors: genGenericAsgn(p, dest, src, flags) - elif (needToCopy notin flags and src.storage != OnStatic) or canMove(src.lode): + elif (needToCopy notin flags and src.storage != OnStatic) or canMove(p, src.lode): genRefAssign(p, dest, src, flags) else: if dest.storage == OnStack or not usesWriteBarrier(p.config): diff --git a/tests/ccgbugs/tassign_nil_strings.nim b/tests/ccgbugs/tassign_nil_strings.nim new file mode 100644 index 000000000..07d2c2aeb --- /dev/null +++ b/tests/ccgbugs/tassign_nil_strings.nim @@ -0,0 +1,13 @@ +discard """ + cmd: "nim $target --nilseqs:off $options $file" + output: "Hello" + ccodecheck: "\\i@'a = ((NimStringDesc*) NIM_NIL)'" +""" + +proc main() = + var a = "Hello" + echo a + a = "" + doAssert a.len == 0 + +main() |