compiler: use correct init order for multi-value initialization
commitfbd7665360d259434f378f68cb2680b17d6cab57
authorIan Lance Taylor <iant@golang.org>
Fri, 1 Jul 2022 00:40:00 +0000 (30 17:40 -0700)
committerIan Lance Taylor <iant@golang.org>
Fri, 1 Jul 2022 22:45:34 +0000 (1 15:45 -0700)
treeceac82da99be61210976ee3c8882b435fdf72668
parent1697806fdf25285b924251b0d785324775e9b905
compiler: use correct init order for multi-value initialization

Use the correct initialization order for

var a = c
var b, c = x.(bool)

The global c is initialized by the preinit of b, but were missing a
dependency of c on b, so a would be initialized to the zero value of c
rather than the correct value.

Simply adding the dependency of c on b didn't work because the preinit
of b refers to c, so that appeared circular.  So this patch changes
the init order to skip dependencies that only appear on the left hand
side of assignments in preinit blocks.

Doing that didn't work because the write barrier pass can transform "a
= b" into code like "gcWriteBarrier(&a, b)" that is not obviously a
simple assigment.  So this patch moves the collection of dependencies
to just after lowering, before the write barriers are inserted.

Making those changes permit relaxing the requirement that we don't
warn about self-dependency in preinit blocks, so now we correctly warn
for

var a, b any = b.(bool)

The test case is https://go.dev/cl/415238.

Fixes golang/go#53619

Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/415594
gcc/go/gofrontend/MERGE
gcc/go/gofrontend/go.cc
gcc/go/gofrontend/gogo.cc
gcc/go/gofrontend/gogo.h
gcc/go/gofrontend/parse.cc