Skip to content

Commit f009ea6

Browse files
authored
fixes #25208; generates a copy for opcLdConst in the assignments (#25211)
fixes #25208 ```nim type Conf = object val: int const defaultConf = Conf(val: 123) static: var conf: Conf conf = defaultConf ``` ```nim # opcLdConst is now always valid. We produce the necessary copy in the # assignments now: ``` A `opcLdConst` is generated for `defaultConf` in `conf = defaultConf`. According to the comment above, we need to handle the copy for assignments of `opcLdConst`
1 parent 8f3bdb6 commit f009ea6

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

compiler/vmgen.nim

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,12 +1609,12 @@ proc genAdditionalCopy(c: PCtx; n: PNode; opc: TOpcode;
16091609
c.freeTemp(cc)
16101610

16111611
proc preventFalseAlias(c: PCtx; n: PNode; opc: TOpcode;
1612-
dest, idx, value: TRegister) =
1612+
dest, idx, value: TRegister; enforceCopy = false) =
16131613
# opcLdObj et al really means "load address". We sometimes have to create a
16141614
# copy in order to not introduce false aliasing:
16151615
# mylocal = a.b # needs a copy of the data!
16161616
assert n.typ != nil
1617-
if needsAdditionalCopy(n):
1617+
if needsAdditionalCopy(n) or enforceCopy:
16181618
genAdditionalCopy(c, n, opc, dest, idx, value)
16191619
else:
16201620
c.gABC(n, opc, dest, idx, value)
@@ -1663,11 +1663,14 @@ proc genAsgn(c: PCtx; le, ri: PNode; requiresCopy: bool) =
16631663
of nkSym:
16641664
let s = le.sym
16651665
checkCanEval(c, le)
1666+
let isLdConst = ri.kind == nkSym and ri.sym.kind == skConst and
1667+
dontInlineConstant(ri, if ri.sym.astdef != nil: ri.sym.astdef else: ri.sym.typ.n)
1668+
# assigning a constant (opcLdConst) to something; need to copy its value
16661669
if s.isGlobal:
16671670
withTemp(tmp, le.typ):
16681671
c.gen(le, tmp, {gfNodeAddr})
16691672
let val = c.genx(ri)
1670-
c.preventFalseAlias(le, opcWrDeref, tmp, 0, val)
1673+
c.preventFalseAlias(le, opcWrDeref, tmp, 0, val, isLdConst)
16711674
c.freeTemp(val)
16721675
else:
16731676
if s.kind == skForVar: c.setSlot s

tests/vm/tvmmisc.nim

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,3 +794,22 @@ block: # bug #23925
794794
static: # bug #21353
795795
var s: proc () = default(proc ())
796796
doAssert s == nil
797+
798+
# bug #25208
799+
800+
801+
type Conf = object
802+
val: int
803+
804+
const defaultConf = Conf(val: 123)
805+
806+
template foo2323(conf) =
807+
assert conf.val == 123
808+
var conf2 = conf
809+
assert conf2.val == 123
810+
811+
static:
812+
var conf: Conf = defaultConf
813+
conf = defaultConf # removing this results in the expected output
814+
conf.val = 2
815+
foo2323(defaultConf)

0 commit comments

Comments
 (0)