Skip to content

Commit

Permalink
fixes #21540; deref block at transf phase to make injectdestructors f…
Browse files Browse the repository at this point in the history
…unction properly (#21688)

* fixes #21540; deref block at transf phase to make injectdestructors function properly

* add a test case

* add one more test

* fixes the type of block

* transform block
  • Loading branch information
ringabout authored Apr 19, 2023
1 parent 0d6b994 commit 9cb06d3
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 17 deletions.
15 changes: 1 addition & 14 deletions compiler/ccgexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -752,21 +752,8 @@ proc isCppRef(p: BProc; typ: PType): bool {.inline.} =
skipTypes(typ, abstractInstOwned).kind in {tyVar} and
tfVarIsPtr notin skipTypes(typ, abstractInstOwned).flags

proc derefBlock(p: BProc, e: PNode, d: var TLoc) =
# We transform (block: x)[] to (block: x[])
let e0 = e[0]
var n = shallowCopy(e0)
n.typ = e.typ
for i in 0 ..< e0.len - 1:
n[i] = e0[i]
n[e0.len-1] = newTreeIT(nkHiddenDeref, e.info, e.typ, e0[e0.len-1])
expr p, n, d

proc genDeref(p: BProc, e: PNode, d: var TLoc) =
if e.kind == nkHiddenDeref and e[0].kind in {nkBlockExpr, nkBlockStmt}:
# bug #20107. Watch out to not deref the pointer too late.
derefBlock(p, e, d)
return
assert e[0].kind notin {nkBlockExpr, nkBlockStmt}, "it should have been transformed in transf"

let mt = mapType(p.config, e[0].typ, mapTypeChooser(e[0]))
if mt in {ctArray, ctPtrToArray} and lfEnforceDeref notin d.flags:
Expand Down
16 changes: 15 additions & 1 deletion compiler/transf.nim
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,15 @@ proc commonOptimizations*(g: ModuleGraph; idgen: IdGenerator; c: PSym, n: PNode)
else:
result = n

proc transformDerefBlock(c: PTransf, n: PNode): PNode =
# We transform (block: x)[] to (block: x[])
let e0 = n[0]
result = shallowCopy(e0)
result.typ = n.typ
for i in 0 ..< e0.len - 1:
result[i] = e0[i]
result[e0.len-1] = newTreeIT(nkHiddenDeref, n.info, n.typ, e0[e0.len-1])

proc transform(c: PTransf, n: PNode): PNode =
when false:
var oldDeferAnchor: PNode
Expand Down Expand Up @@ -1012,7 +1021,12 @@ proc transform(c: PTransf, n: PNode): PNode =
of nkAddr:
result = transformAddrDeref(c, n, {nkDerefExpr, nkHiddenDeref})
of nkDerefExpr, nkHiddenDeref:
result = transformAddrDeref(c, n, {nkAddr, nkHiddenAddr})
if n[0].kind in {nkBlockExpr, nkBlockStmt}:
# bug #20107 bug #21540. Watch out to not deref the pointer too late.
let e = transformDerefBlock(c, n)
result = transformBlock(c, e)
else:
result = transformAddrDeref(c, n, {nkAddr, nkHiddenAddr})
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
result = transformConv(c, n)
of nkDiscardStmt:
Expand Down
55 changes: 53 additions & 2 deletions tests/ccgbugs/tderefblock.nim
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
discard """
cmd: "nim c -d:release -d:danger $file"
matrix: ";--gc:orc"
matrix: "--mm:refc -d:release -d:danger;--mm:orc -d:useMalloc -d:release -d:danger"
output: "42"
"""

Expand All @@ -23,3 +22,55 @@ proc m() =
echo $f.a

m()

block: # bug #21540
type
Option = object
val: string
has: bool

proc some(val: string): Option =
result.has = true
result.val = val

# Remove lent and it works
proc get(self: Option): lent string =
result = self.val

type
StringStream = ref object
data: string
pos: int

proc readAll(s: StringStream): string =
result = newString(s.data.len)
copyMem(addr(result[0]), addr(s.data[0]), s.data.len)

proc newStringStream(s: string = ""): StringStream =
new(result)
result.data = s

proc parseJson(s: string): string =
let stream = newStringStream(s)
result = stream.readAll()

proc main =
let initialFEN = block:
let initialFEN = some parseJson("startpos")
initialFEN.get

doAssert initialFEN == "startpos"

main()

import std/[
json,
options
]

block: # bug #21540
let cheek = block:
let initialFEN = some("""{"initialFen": "startpos"}""".parseJson{"initialFen"}.getStr)
initialFEN.get

doAssert cheek == "startpos"

0 comments on commit 9cb06d3

Please sign in to comment.