diff --git a/compiler/ccgreset.nim b/compiler/ccgreset.nim index 707d37f81d..2fa562ee53 100644 --- a/compiler/ccgreset.nim +++ b/compiler/ccgreset.nim @@ -73,23 +73,6 @@ proc specializeResetT(p: BProc, accessor: Rope, typ: PType) = [accessor, getTypeDesc(p.module, typ)]) else: specializeResetN(p, accessor, typ.n, typ) - if isCaseObj(typ.n): - # The active branch was released above. Clear the complete object so - # stale bytes from overlapping branches cannot be traced by the GC. - # type - # Foo = object - # case kind: bool - # of true: - # a: ref Bar # 8 bytes (pointer) - # of false: - # b: int # 4 bytes - # specializeResetT for b emits accessor.b = 0 — writes 4 bytes - # But the union is 8 bytes wide (sized by the largest branch) - # The remaining 4 bytes where a used to live are untouched - # Those stale bytes could contain a heap pointer the GC traces → crash - p.s(cpsStmts).addCallStmt(cgsymValue(p.module, "nimZeroMem"), - cCast(CPointer, cAddr(accessor)), - cSizeof(getTypeDesc(p.module, typ))) of tyTuple: let typ = getUniqueType(typ) for i, a in typ.ikids: diff --git a/tests/gc/tmove_case_object.nim b/tests/gc/tmove_case_object.nim deleted file mode 100644 index 8f4d9ba450..0000000000 --- a/tests/gc/tmove_case_object.nim +++ /dev/null @@ -1,56 +0,0 @@ -discard """ - matrix: "--mm:refc; --mm:orc" -""" - -type - A = object of RootObj - - V = object - case g: bool - of true: - v: A - of false: - e: string - -var r = V(g: true, v: A()) -discard move r -GC_fullCollect() - -type - Kind = enum nested, other - Nested = object - case kind: Kind - of nested: - case enabled: bool - of true: payload: A - of false: message: string - of other: - discard - -var n = Nested(kind: nested, enabled: true, payload: A()) -discard move n -GC_fullCollect() - -# Moving from the other branch must keep its value alive and leave the source -# in the default state. -var s = V(g: false, e: "hello") -let moved = move s -doAssert moved.e == "hello" -doAssert not s.g -doAssert s.e.len == 0 - -# Reinitializing the zeroed value must also restore embedded object type -# headers. -type W = object - a: A - value: V - text: string - -var w = W(a: A(), value: V(g: true, v: A()), text: "content") -let movedW = move w -doAssert movedW.text == "content" -doAssert cast[ptr pointer](addr w.a)[] != nil -doAssert not w.value.g -doAssert w.value.e.len == 0 -doAssert w.text.len == 0 -GC_fullCollect()