Skip to content

Commit

Permalink
fix fitsRegister, fix nim-lang#18641
Browse files Browse the repository at this point in the history
  • Loading branch information
timotheecour committed Aug 3, 2021
1 parent 147791c commit 41508aa
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 3 deletions.
6 changes: 6 additions & 0 deletions compiler/semstmts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ proc semIdentDef(c: PContext, n: PNode, kind: TSymKind): PSym =
else:
result = semIdentWithPragma(c, kind, n, {})
if result.owner.kind == skModule:
# if result.owner.kind in {skModule, skLabel}:
incl(result.flags, sfGlobal)
result.options = c.config.options

Expand Down Expand Up @@ -2239,8 +2240,13 @@ proc semStaticStmt(c: PContext, n: PNode): PNode =
#writeStackTrace()
inc c.inStaticContext
openScope(c)
# var ownerOld: PSym = nil
# if c.config.isDefined("nim_pushStaticContext"):
# ownerOld = pushStaticContext(c, n)
let ownerOld = pushStaticContext(c, n)
let a = semStmt(c, n[0], {})
# if c.config.isDefined("nim_pushStaticContext"):
# popStaticContext(c, ownerOld)
popStaticContext(c, ownerOld)
closeScope(c)
dec c.inStaticContext
Expand Down
20 changes: 17 additions & 3 deletions compiler/vmgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,9 @@ proc genCall(c: PCtx; n: PNode; dest: var TDest) =
c.gABC(n, opcIndCallAsgn, dest, x, n.len)
c.freeTempRange(x, n.len)

template isGlobal(s: PSym): bool = sfGlobal in s.flags and s.kind != skForVar
template isGlobal(s: PSym): bool =
# (sfGlobal in s.flags and s.kind != skForVar) or (s.owner != nil and s.owner.kind == skLabel)
(sfGlobal in s.flags and s.kind != skForVar)
proc isGlobal(n: PNode): bool = n.kind == nkSym and isGlobal(n.sym)

proc needsAsgnPatch(n: PNode): bool =
Expand Down Expand Up @@ -986,7 +988,8 @@ proc genBindSym(c: PCtx; n: PNode; dest: var TDest) =
proc fitsRegister*(t: PType): bool =
assert t != nil
t.skipTypes(abstractInst + {tyStatic} - {tyTypeDesc}).kind in {
tyRange, tyEnum, tyBool, tyInt..tyUInt64, tyChar}
# tyRange, tyEnum, tyBool, tyInt..tyUInt64, tyChar}
tyRange, tyEnum, tyBool, tyInt..tyUInt64, tyChar, tyPtr} # PRTEMP

proc ldNullOpcode(t: PType): TOpcode =
assert t != nil
Expand Down Expand Up @@ -1634,6 +1637,8 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
# gfNodeAddr and gfNode are mutually exclusive
assert card(flags * {gfNodeAddr, gfNode}) < 2
let s = n.sym
dbgIf s, c.config$n.info, n, s.isGlobal, s.kind, s.owner, flags, s.position, dest
dbgIf getStacktrace()
if s.isGlobal:
let isImportcVar = importcCondVar(s)
if sfCompileTime in s.flags or c.mode == emRepl or isImportcVar:
Expand Down Expand Up @@ -1666,7 +1671,8 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
s.kind in {skParam, skResult}):
if dest < 0:
dest = s.position + ord(s.kind == skParam)
internalAssert(c.config, c.prc.regInfo[dest].kind < slotSomeTemp)
# internalAssert(c.config, c.prc.regInfo[dest].kind < slotSomeTemp)
discard
else:
# we need to generate an assignment:
let requiresCopy = c.prc.regInfo[dest].kind >= slotSomeTemp and
Expand Down Expand Up @@ -1853,6 +1859,7 @@ proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode =
result = newNodeI(nkEmpty, info)

proc genVarSection(c: PCtx; n: PNode) =
dbgIf c.config$n.info, n
for a in n:
if a.kind == nkCommentStmt: continue
#assert(a[0].kind == nkSym) can happen for transformed vars
Expand All @@ -1865,6 +1872,7 @@ proc genVarSection(c: PCtx; n: PNode) =
elif a[0].kind == nkSym:
let s = a[0].sym
checkCanEval(c, a[0])
dbgIf s, s.kind, s.isGlobal, s.position, a[2].kind
if s.isGlobal:
if s.position == 0:
if importcCond(c, s): c.importcSym(a.info, s)
Expand All @@ -1876,8 +1884,10 @@ proc genVarSection(c: PCtx; n: PNode) =
c.globals.add(sa)
s.position = c.globals.len
if a[2].kind != nkEmpty:
dbgIf "gfNodeAddr"
let tmp = c.genx(a[0], {gfNodeAddr})
let val = c.genx(a[2])
dbgIf tmp, val
c.genAdditionalCopy(a[2], opcWrDeref, tmp, 0, val)
c.freeTemp(val)
c.freeTemp(tmp)
Expand All @@ -1887,16 +1897,20 @@ proc genVarSection(c: PCtx; n: PNode) =
c.gABx(a, ldNullOpcode(s.typ), s.position, c.genType(s.typ))
else:
assert s.typ != nil
dbgIf fitsRegister(s.typ), s.typ
if not fitsRegister(s.typ):
c.gABx(a, ldNullOpcode(s.typ), s.position, c.genType(s.typ))
let le = a[0]
assert le.typ != nil
dbgIf fitsRegister(le.typ), le.typ
if not fitsRegister(le.typ) and s.kind in {skResult, skVar, skParam}:
dbgIf "not fitsRegister"
var cc = c.getTemp(le.typ)
gen(c, a[2], cc)
c.gABC(le, whichAsgnOpc(le), s.position.TRegister, cc)
c.freeTemp(cc)
else:
dbgIf "fitsRegister"
gen(c, a[2], s.position.TRegister)
else:
# assign to a[0]; happens for closures
Expand Down
37 changes: 37 additions & 0 deletions tests/misc/trfc_276.nim
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,43 @@ when true: # tests with module dependencies
doAssert z1 == @[k0, k1, k2]
fn3()

block: # bug #18641
type A = object
ha1: int
static:
var a = A()
var a2 = a.addr
a2.ha1 = 11
doAssert a2.ha1 == 11
a.ha1 = 12
doAssert a.ha1 == 12
doAssert a2.ha1 == 12
static:
proc fn() =
var a = A()
var a2 = a.addr
a2.ha1 = 11
doAssert a2.ha1 == 11
a.ha1 = 12
doAssert a.ha1 == 12
doAssert a2.ha1 == 12
fn()

block:
type A = object
ha1: int
const z = block:
var a = A()
var a2 = a.addr
a2.ha1 = 11
doAssert a2.ha1 == 11
a.ha1 = 12
doAssert a.ha1 == 12
doAssert a2.ha1 == 12
123
doAssert z == 123


when true:
#[
bug #14645 (only partial fix)
Expand Down
4 changes: 4 additions & 0 deletions tests/stdlib/timportutils.nim
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
discard """
joinable: false
"""

import std/importutils
import stdtest/testutils
import mimportutils
Expand Down

0 comments on commit 41508aa

Please sign in to comment.