mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-20 22:35:24 +00:00
fixes #23858 We should not assign fields to fields for returns of function calls because calls might have side effects.
This commit is contained in:
@@ -141,7 +141,7 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc,
|
||||
if d.k == locNone: d = getTemp(p, typ.returnType)
|
||||
var list = initLoc(locCall, d.lode, OnUnknown)
|
||||
list.snippet = pl
|
||||
genAssignment(p, d, list, {}) # no need for deep copying
|
||||
genAssignment(p, d, list, {needAssignCall}) # no need for deep copying
|
||||
if canRaise: raiseExit(p)
|
||||
|
||||
elif isHarmlessStore(p, canRaise, d):
|
||||
@@ -152,7 +152,7 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc,
|
||||
assert(d.t != nil) # generate an assignment to d:
|
||||
var list = initLoc(locCall, d.lode, OnUnknown)
|
||||
list.snippet = pl
|
||||
genAssignment(p, d, list, flags) # no need for deep copying
|
||||
genAssignment(p, d, list, flags+{needAssignCall}) # no need for deep copying
|
||||
if canRaise:
|
||||
if not (useTemp and cleanupTemp(p, typ.returnType, d)):
|
||||
raiseExit(p)
|
||||
@@ -160,7 +160,7 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc,
|
||||
var tmp: TLoc = getTemp(p, typ.returnType, needsInit=true)
|
||||
var list = initLoc(locCall, d.lode, OnUnknown)
|
||||
list.snippet = pl
|
||||
genAssignment(p, tmp, list, flags) # no need for deep copying
|
||||
genAssignment(p, tmp, list, flags+{needAssignCall}) # no need for deep copying
|
||||
if canRaise:
|
||||
if not cleanupTemp(p, typ.returnType, tmp):
|
||||
raiseExit(p)
|
||||
|
||||
@@ -379,7 +379,8 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||
elif not isObjLackingTypeField(ty):
|
||||
genGenericAsgn(p, dest, src, flags)
|
||||
elif containsGarbageCollectedRef(ty):
|
||||
if ty[0].isNil and asgnComplexity(ty.n) <= 4:
|
||||
if ty[0].isNil and asgnComplexity(ty.n) <= 4 and
|
||||
needAssignCall notin flags: # calls might contain side effects
|
||||
discard getTypeDesc(p.module, ty)
|
||||
internalAssert p.config, ty.n != nil
|
||||
genOptAsgnObject(p, dest, src, flags, ty.n, ty)
|
||||
|
||||
@@ -413,6 +413,7 @@ type
|
||||
needToCopy
|
||||
needToCopySinkParam
|
||||
needTempForOpenArray
|
||||
needAssignCall
|
||||
TAssignmentFlags = set[TAssignmentFlag]
|
||||
|
||||
proc genObjConstr(p: BProc, e: PNode, d: var TLoc)
|
||||
|
||||
@@ -160,3 +160,14 @@ block:
|
||||
testCase()
|
||||
|
||||
main()
|
||||
|
||||
block: # bug #23858
|
||||
type Object = object
|
||||
a: int
|
||||
b: ref int
|
||||
var x = 0
|
||||
proc fn(): auto {.cdecl.} =
|
||||
inc x
|
||||
return Object()
|
||||
discard fn()
|
||||
doAssert x == 1
|
||||
|
||||
Reference in New Issue
Block a user