cmd/compile: add missing OINLCAll case in mayModifyPkgVar

CL 395541 made staticopy safe, stop applying the optimization once
seeing an expression that may modify global variables.

However, if a call expression was inlined, the analyzer mis-recognizes
and think that the expression is safe. For example:

	var x = 0
	var a = f()
	var b = x

are re-written to:

	var x = 0
	var a = ~r0
	var b = 0

even though it's not safe because "f()" may modify "x".

Fixing this by recognizing OINLCALL and mark the initialization as
not safe for staticopy.

Fixes #66585

Change-Id: Id930c0b7e74274195f54a498cc4c5a91c4e6d84d
Reviewed-on: https://go-review.googlesource.com/c/go/+/575175
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Than McIntosh <thanm@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Cuong Manh Le 2024-03-29 15:00:09 +07:00 committed by Gopher Robot
parent 27c7a3dcc3
commit 9a028e14a5
2 changed files with 28 additions and 0 deletions

View file

@ -890,6 +890,9 @@ func mayModifyPkgVar(n ir.Node) bool {
case ir.OCALLFUNC, ir.OCALLINTER:
return !ir.IsFuncPCIntrinsic(n.(*ir.CallExpr))
case ir.OINLCALL:
return true
case ir.OAPPEND, ir.OCLEAR, ir.OCOPY:
return true // could mutate a global array

View file

@ -0,0 +1,25 @@
// run
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
var x = 0
var a = foo()
var b = x
func foo() int {
x++
return x
}
func main() {
if a != 1 {
panic("unexpected a value")
}
if b != 1 {
panic("unexpected b value")
}
}