fixes #23627; Simple destructor code gives invalid C (#23631)

fixes #23627

```nim
type
  TestObj = object of RootObj

  TestTestObj = object of RootObj
    testo: TestObj

proc `=destroy`(x: TestTestObj) =
  echo "Destructor for TestTestObj"

proc testCaseT() =
  echo "\nTest Case T"
  let tt1 {.used.} = TestTestObj(testo: TestObj())
```

When generating const object fields, it's likely that
we need to generate type infos for the object, which may be an object
with
custom hooks. We need to generate potential consts in the hooks first.

https://github.com/nim-lang/Nim/pull/20433 changed the semantics of
initialization. It should evaluate`BracedInit` first.
This commit is contained in:
ringabout
2024-05-21 20:53:08 +08:00
committed by GitHub
parent b838d3ece1
commit 309f97af4c
2 changed files with 36 additions and 8 deletions

View File

@@ -1484,9 +1484,13 @@ proc rawConstExpr(p: BProc, n: PNode; d: var TLoc) =
if id == p.module.labels:
# expression not found in the cache:
inc(p.module.labels)
p.module.s[cfsData].addf("static NIM_CONST $1 $2 = ", [getTypeDesc(p.module, t), d.r])
genBracedInit(p, n, isConst = true, t, p.module.s[cfsData])
p.module.s[cfsData].addf(";$n", [])
var data = "static NIM_CONST $1 $2 = " % [getTypeDesc(p.module, t), d.r]
# bug #23627; when generating const object fields, it's likely that
# we need to generate type infos for the object, which may be an object with
# custom hooks. We need to generate potential consts in the hooks first.
genBracedInit(p, n, isConst = true, t, data)
data.addf(";$n", [])
p.module.s[cfsData].add data
proc handleConstExpr(p: BProc, n: PNode, d: var TLoc): bool =
if d.k == locNone and n.len > ord(n.kind == nkObjConstr) and n.isDeepConstExpr:

View File

@@ -1,5 +1,6 @@
discard """
output: '''
Destructor for TestTestObj
=destroy called
123xyzabc
destroyed: false
@@ -36,9 +37,33 @@ destroying variable: 20
destroying variable: 10
closed
'''
cmd: "nim c --gc:arc --deepcopy:on -d:nimAllocPagesViaMalloc $file"
cmd: "nim c --mm:arc --deepcopy:on -d:nimAllocPagesViaMalloc $file"
"""
block: # bug #23627
type
TestObj = object of RootObj
Test2 = object of RootObj
foo: TestObj
TestTestObj = object of RootObj
shit: TestObj
proc `=destroy`(x: TestTestObj) =
echo "Destructor for TestTestObj"
let test = Test2(foo: TestObj())
proc testCaseT() =
let tt1 {.used.} = TestTestObj(shit: TestObj())
proc main() =
testCaseT()
main()
# bug #9401
type
@@ -46,13 +71,12 @@ type
len: int
data: ptr UncheckedArray[float]
proc `=destroy`*(m: var MyObj) =
proc `=destroy`*(m: MyObj) =
echo "=destroy called"
if m.data != nil:
deallocShared(m.data)
m.data = nil
type
MyObjDistinct = distinct MyObj
@@ -104,7 +128,7 @@ bbb("123")
type Variable = ref object
value: int
proc `=destroy`(self: var typeof(Variable()[])) =
proc `=destroy`(self: typeof(Variable()[])) =
echo "destroying variable: ",self.value
proc newVariable(value: int): Variable =
@@ -158,7 +182,7 @@ type
B = ref object of A
x: int
proc `=destroy`(x: var AObj) =
proc `=destroy`(x: AObj) =
close(x.io)
echo "closed"