fixes #23858; 2.2.0 rc1 regression with cdecl functions (#23859)

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:
ringabout
2024-07-19 02:53:07 +08:00
committed by GitHub
parent 6aa54d533b
commit 3a103669d1
4 changed files with 17 additions and 4 deletions

View File

@@ -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)

View File

@@ -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)

View File

@@ -413,6 +413,7 @@ type
needToCopy
needToCopySinkParam
needTempForOpenArray
needAssignCall
TAssignmentFlags = set[TAssignmentFlag]
proc genObjConstr(p: BProc, e: PNode, d: var TLoc)

View File

@@ -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