Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: package-level variable initialization order looks not correct #66585

Closed
zigo101 opened this issue Mar 28, 2024 · 12 comments
Closed
Assignees
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@zigo101
Copy link

zigo101 commented Mar 28, 2024

Go version

go version go1.22.1 linux/amd64

Output of go env in your module/workspace:

.

What did you do?

package main

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

func foo() int {
	x++
	return x
}

func main() {
	println(a, b) // 1 0
}

What did you see happen?

1 0

What did you expect to see?

1 1

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Mar 28, 2024
@ianlancetaylor
Copy link
Contributor

CC @griesemer

gccgo prints 1 1.

@griesemer griesemer self-assigned this Mar 28, 2024
@griesemer
Copy link
Contributor

It looks like the type checker is computing the correct order. Here is the initorder trace for the above code:

== initOrder ==
Computing initialization order for package p ("p")

Object dependency graph:
        x has no dependencies
        a depends on
                foo
        b depends on
                x
        foo depends on
                x
        main depends on
                a
                b

Transposed object dependency graph (functions eliminated):
        x depends on 0 nodes
                b is dependent
                a is dependent
        a depends on 1 nodes
        b depends on 1 nodes

Processing nodes:
        x (src pos 1) depends on 0 nodes now
        a (src pos 2) depends on 0 nodes now
        b (src pos 3) depends on 0 nodes now

Initialization order:
        x = 0
        a = foo()
        b = x

@griesemer griesemer removed their assignment Mar 28, 2024
@griesemer griesemer added this to the Go1.23 milestone Mar 28, 2024
@randall77
Copy link
Contributor

randall77 commented Mar 28, 2024

Yes, this looks like cmd/compile/internal/staticinit not getting it right somehow.
Initorder is generally computed and passed through unified IR export/import correctly. But then we don't use it? Something is odd here.

@kungfukennyg
Copy link

I'd like to dig further into this issue if no one else is claiming it.

@mainjzb
Copy link

mainjzb commented Mar 29, 2024

change to this

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

func foo() int {
	x = x + 1       // diferent
	return x
}

func main() {
	println(a, b)
        // 1 1 # go1.22
        // 1 0 # go1.21
}

@cuonglm cuonglm self-assigned this Mar 29, 2024
@cuonglm cuonglm added the NeedsFix The path to resolution is known, but the work has not been done. label Mar 29, 2024
@cuonglm
Copy link
Member

cuonglm commented Mar 29, 2024

This is a bug in staticinit, where the compiler try optimizing:

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

to:

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

without recognizing that the optimization is unsafe, because foo was inlined.

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/575175 mentions this issue: cmd/compile: add missing OINLCAll case in mayModifyPkgVar

@dmitshur
Copy link
Contributor

Reopening since the fix in CL 575175 was rolled back in CL 575316.

@dmitshur dmitshur reopened this Mar 29, 2024
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/575216 mentions this issue: cmd/compile: add missing OASOP case in mayModifyPkgVar

@cuonglm
Copy link
Member

cuonglm commented Mar 29, 2024

@randall77 Should we backport this issue? Though it's not a regression, it causes mis-compilation and make binary behaves wrongly.

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/575336 mentions this issue: cmd/compile: check ODEREF for safe lhs in assignment during static init

@randall77
Copy link
Contributor

I don't think we should backport this. It is not a problem that any realistic program runs into, and it is easy to work around if it does.

gopherbot pushed a commit that referenced this issue Apr 2, 2024
For #66585

Change-Id: Iddc407e3ef4c3b6ecf5173963b66b3e65e43c92d
Reviewed-on: https://go-review.googlesource.com/c/go/+/575336
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@golang.org>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

9 participants