mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 08:54:53 +00:00
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`
This commit is contained in:
@@ -1609,12 +1609,12 @@ proc genAdditionalCopy(c: PCtx; n: PNode; opc: TOpcode;
|
||||
c.freeTemp(cc)
|
||||
|
||||
proc preventFalseAlias(c: PCtx; n: PNode; opc: TOpcode;
|
||||
dest, idx, value: TRegister) =
|
||||
dest, idx, value: TRegister; enforceCopy = false) =
|
||||
# opcLdObj et al really means "load address". We sometimes have to create a
|
||||
# copy in order to not introduce false aliasing:
|
||||
# mylocal = a.b # needs a copy of the data!
|
||||
assert n.typ != nil
|
||||
if needsAdditionalCopy(n):
|
||||
if needsAdditionalCopy(n) or enforceCopy:
|
||||
genAdditionalCopy(c, n, opc, dest, idx, value)
|
||||
else:
|
||||
c.gABC(n, opc, dest, idx, value)
|
||||
@@ -1663,11 +1663,14 @@ proc genAsgn(c: PCtx; le, ri: PNode; requiresCopy: bool) =
|
||||
of nkSym:
|
||||
let s = le.sym
|
||||
checkCanEval(c, le)
|
||||
let isLdConst = ri.kind == nkSym and ri.sym.kind == skConst and
|
||||
dontInlineConstant(ri, if ri.sym.astdef != nil: ri.sym.astdef else: ri.sym.typ.n)
|
||||
# assigning a constant (opcLdConst) to something; need to copy its value
|
||||
if s.isGlobal:
|
||||
withTemp(tmp, le.typ):
|
||||
c.gen(le, tmp, {gfNodeAddr})
|
||||
let val = c.genx(ri)
|
||||
c.preventFalseAlias(le, opcWrDeref, tmp, 0, val)
|
||||
c.preventFalseAlias(le, opcWrDeref, tmp, 0, val, isLdConst)
|
||||
c.freeTemp(val)
|
||||
else:
|
||||
if s.kind == skForVar: c.setSlot s
|
||||
|
||||
@@ -794,3 +794,22 @@ block: # bug #23925
|
||||
static: # bug #21353
|
||||
var s: proc () = default(proc ())
|
||||
doAssert s == nil
|
||||
|
||||
# bug #25208
|
||||
|
||||
|
||||
type Conf = object
|
||||
val: int
|
||||
|
||||
const defaultConf = Conf(val: 123)
|
||||
|
||||
template foo2323(conf) =
|
||||
assert conf.val == 123
|
||||
var conf2 = conf
|
||||
assert conf2.val == 123
|
||||
|
||||
static:
|
||||
var conf: Conf = defaultConf
|
||||
conf = defaultConf # removing this results in the expected output
|
||||
conf.val = 2
|
||||
foo2323(defaultConf)
|
||||
|
||||
Reference in New Issue
Block a user