Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions compiler/injectdestructors.nim
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,11 @@ proc isLastReadImpl(n: PNode; c: var Con; scope: var Scope): bool =

template hasDestructorOrAsgn(c: var Con, typ: PType): bool =
# bug #23354; an object type could have a non-trivial assignements when it is passed to a sink parameter
hasDestructor(c, typ) or (c.graph.config.selectedGC in {gcArc, gcOrc, gcAtomicArc} and
hasDestructor(c, typ) or (c.graph.config.selectedGC == gcRefc and typ.kind == tyString) or (c.graph.config.selectedGC in {gcArc, gcOrc, gcAtomicArc} and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same for seq?

typ.kind == tyObject and not isTrivial(getAttachedOp(c.graph, typ, attachedAsgn)))

proc isLastRead(n: PNode; c: var Con; s: var Scope): bool =
if not hasDestructorOrAsgn(c, n.typ): return true
if not hasDestructorOrAsgn(c, n.typ.skipTypes({tyGenericInst, tyAlias, tySink})): return true

let m = skipConvDfa(n)
result = isLastReadImpl(n, c, s)
Expand Down Expand Up @@ -286,7 +286,9 @@ proc deepAliases(dest, ri: PNode): bool =
return aliases(dest, ri) != no

proc genSink(c: var Con; s: var Scope; dest, ri: PNode; flags: set[MoveOrCopyFlag] = {}): PNode =
if (c.inLoopCond == 0 and (isFullyUnpackedTuple(dest) or IsDecl in flags or
if c.graph.config.selectedGC == gcRefc and dest.typ.skipTypes({tyGenericInst, tyAlias, tySink}).kind == tyString:
result = newFastAsgnStmt(dest, callCodegenProc(c.graph, "moveString", dest.info, ri))
elif (c.inLoopCond == 0 and (isFullyUnpackedTuple(dest) or IsDecl in flags or
(isAnalysableFieldAccess(dest, c.owner) and isFirstWrite(dest, c)))) or
isNoInit(dest) or IsReturn in flags:
# optimize sink call into a bitwise memcopy
Expand Down
2 changes: 2 additions & 0 deletions compiler/liftdestructors.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1036,6 +1036,8 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) =
of tyString:
if useNoGc(c, t):
useSeqOrStrOp(c, t, body, x, y)
elif c.g.config.selectedGC == gcRefc:
defaultOp(c, t, body, x, y)
elif tfHasAsgn in t.flags:
discard considerUserDefinedOp(c, t, body, x, y)
else:
Expand Down
2 changes: 1 addition & 1 deletion compiler/semtypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2430,7 +2430,7 @@ proc processMagicType(c: PContext, m: PSym) =
of mString:
setMagicType(c.config, m, tyString, szUncomputedSize)
rawAddSon(m.typ, getSysType(c.graph, m.info, tyChar))
if optSeqDestructors in c.config.globalOptions:
if optSeqDestructors in c.config.globalOptions or c.config.selectedGC == gcRefc:
incl m.typ, tfHasAsgn
of mCstring:
setMagicIntegral(c.config, m, tyCstring, c.config.target.ptrSize)
Expand Down
6 changes: 6 additions & 0 deletions lib/system/sysstr.nim
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ proc cstrToNimstr(str: cstring): NimString {.compilerRtl.} =
if str == nil: NimString(nil)
else: toNimStr(str, str.len)

proc moveString(src: NimString): NimString {.compilerRtl.} =
if (src.reserved and strlitFlag) != 0:
result = toOwnedCopy(src)
else:
result = src

proc copyString(src: NimString): NimString {.compilerRtl.} =
## Expects `src` to be initialized (len and terminating zero set)
if src != nil:
Expand Down
Loading