Skip to content

Commit

Permalink
Fix #18079 Illegal storage access compiling call with nested ref/deref (
Browse files Browse the repository at this point in the history
#20738)

* add test case
* refactoring transformAddrDeref and fix #18079
* fix jsgen
  • Loading branch information
bung87 authored Nov 4, 2022
1 parent 12a20b9 commit ecc8f61
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 9 deletions.
11 changes: 10 additions & 1 deletion compiler/ccgexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3046,7 +3046,16 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
of nkObjConstr: genObjConstr(p, n, d)
of nkCast: genCast(p, n, d)
of nkHiddenStdConv, nkHiddenSubConv, nkConv: genConv(p, n, d)
of nkHiddenAddr, nkAddr: genAddr(p, n, d)
of nkHiddenAddr:
if n[0].kind == nkDerefExpr:
# addr ( deref ( x )) --> x
var x = n[0][0]
if n.typ.skipTypes(abstractVar).kind != tyOpenArray:
x.typ = n.typ
expr(p, x, d)
return
genAddr(p, n, d)
of nkAddr: genAddr(p, n, d)
of nkBracketExpr: genBracketExpr(p, n, d)
of nkDerefExpr, nkHiddenDeref: genDeref(p, n, d)
of nkDotExpr: genRecordField(p, n, d)
Expand Down
7 changes: 7 additions & 0 deletions compiler/jsgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1422,6 +1422,13 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
gen(p, n[0], r)
of nkHiddenDeref:
gen(p, n[0], r)
of nkDerefExpr:
var x = n[0]
if n.kind == nkHiddenAddr:
x = n[0][0]
if n.typ.skipTypes(abstractVar).kind != tyOpenArray:
x.typ = n.typ
gen(p, x, r)
of nkHiddenAddr:
gen(p, n[0], r)
of nkConv:
Expand Down
18 changes: 10 additions & 8 deletions compiler/transf.nim
Original file line number Diff line number Diff line change
Expand Up @@ -459,14 +459,14 @@ proc transformYield(c: PTransf, n: PNode): PNode =
for i, child in changeNode:
child.info = changeNode.info

proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PNode =
proc transformAddrDeref(c: PTransf, n: PNode, kinds: TNodeKinds): PNode =
result = transformSons(c, n)
if c.graph.config.backend == backendCpp or sfCompileToCpp in c.module.flags: return
var n = result
case n[0].kind
of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
var m = n[0][0]
if m.kind == a or m.kind == b:
if m.kind in kinds:
# addr ( nkConv ( deref ( x ) ) ) --> nkConv(x)
n[0][0] = m[0]
result = n[0]
Expand All @@ -476,7 +476,7 @@ proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PNode =
result.typ = toVar(result.typ, n.typ.skipTypes(abstractInst).kind, c.idgen)
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
var m = n[0][1]
if m.kind == a or m.kind == b:
if m.kind in kinds:
# addr ( nkConv ( deref ( x ) ) ) --> nkConv(x)
n[0][1] = m[0]
result = n[0]
Expand All @@ -485,7 +485,7 @@ proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PNode =
elif n.typ.skipTypes(abstractInst).kind in {tyVar}:
result.typ = toVar(result.typ, n.typ.skipTypes(abstractInst).kind, c.idgen)
else:
if n[0].kind == a or n[0].kind == b:
if n[0].kind in kinds:
# addr ( deref ( x )) --> x
result = n[0][0]
if n.typ.skipTypes(abstractVar).kind != tyOpenArray:
Expand Down Expand Up @@ -853,7 +853,7 @@ proc transformCall(c: PTransf, n: PNode): PNode =
elif magic == mAddr:
result = newTransNode(nkAddr, n, 1)
result[0] = n[1]
result = transformAddrDeref(c, result, nkDerefExpr, nkHiddenDeref)
result = transformAddrDeref(c, result, {nkDerefExpr, nkHiddenDeref})
elif magic in {mNBindSym, mTypeOf, mRunnableExamples}:
# for bindSym(myconst) we MUST NOT perform constant folding:
result = n
Expand Down Expand Up @@ -1005,10 +1005,12 @@ proc transform(c: PTransf, n: PNode): PNode =
of nkBreakStmt: result = transformBreak(c, n)
of nkCallKinds:
result = transformCall(c, n)
of nkAddr, nkHiddenAddr:
result = transformAddrDeref(c, n, nkDerefExpr, nkHiddenDeref)
of nkHiddenAddr:
result = transformAddrDeref(c, n, {nkHiddenDeref})
of nkAddr:
result = transformAddrDeref(c, n, {nkDerefExpr, nkHiddenDeref})
of nkDerefExpr, nkHiddenDeref:
result = transformAddrDeref(c, n, nkAddr, nkHiddenAddr)
result = transformAddrDeref(c, n, {nkAddr, nkHiddenAddr})
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
result = transformConv(c, n)
of nkDiscardStmt:
Expand Down
11 changes: 11 additions & 0 deletions tests/misc/t18079.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
type
Foo = object
y: int

Bar = object
x: Foo

proc baz(state: var Bar):int =
state.x.y = 2
state.x.y
doAssert baz((ref Bar)(x: (new Foo)[])[]) == 2

0 comments on commit ecc8f61

Please sign in to comment.