]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix instantiation of types referenced during inlining
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Wed, 5 Jan 2022 09:19:19 +0000 (16:19 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Fri, 7 Jan 2022 17:55:52 +0000 (17:55 +0000)
CL 352870 added extra phase for instantiation after inlining, to take
care of the new fully-instantiated types. However, when fetching inlined
body of these types's methods, we need to allow OADDR operations on
untyped expressions, the same as what main inlining phase does.

The problem does not show up, until CL 371554, which made the compiler
do not re-typecheck while importing, thus leaving a OXDOT node to be
marked as address taken when it's not safe to do that.

Fixes #50437

Change-Id: I20076b872182c520075a4f8b84230f5bcb05b341
Reviewed-on: https://go-review.googlesource.com/c/go/+/375574
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dan Scales <danscales@google.com>
Trust: Dan Scales <danscales@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/gc/main.go
src/cmd/compile/internal/typecheck/subr.go
test/typeparam/issue50437.dir/a.go [new file with mode: 0644]
test/typeparam/issue50437.dir/b.go [new file with mode: 0644]
test/typeparam/issue50437.go [new file with mode: 0644]

index ed81ef7bc0471458df4387387a3466c1979badf6..669e53d9324f6dc37c529c38d64c762ac46f089a 100644 (file)
@@ -248,7 +248,12 @@ func Main(archInit func(*ssagen.ArchInfo)) {
                // If any new fully-instantiated types were referenced during
                // inlining, we need to create needed instantiations.
                if len(typecheck.GetInstTypeList()) > 0 {
+                       // typecheck.IncrementalAddrtaken must be false when loading
+                       // an inlined body. See comment in typecheck.ImportedBody function.
+                       old := typecheck.IncrementalAddrtaken
+                       typecheck.IncrementalAddrtaken = false
                        noder.BuildInstantiations(false)
+                       typecheck.IncrementalAddrtaken = old
                }
        }
        noder.MakeWrappers(typecheck.Target) // must happen after inlining
index 5b5b04371517516c8af7e3a5d79f39cfa4b9b38d..da5e9645eaa897ee343494f9086eb36c92a33dd1 100644 (file)
@@ -80,7 +80,7 @@ func markAddrOf(n ir.Node) ir.Node {
        if IncrementalAddrtaken {
                // We can only do incremental addrtaken computation when it is ok
                // to typecheck the argument of the OADDR. That's only safe after the
-               // main typecheck has completed.
+               // main typecheck has completed, and not loading the inlined body.
                // The argument to OADDR needs to be typechecked because &x[i] takes
                // the address of x if x is an array, but not if x is a slice.
                // Note: OuterValue doesn't work correctly until n is typechecked.
diff --git a/test/typeparam/issue50437.dir/a.go b/test/typeparam/issue50437.dir/a.go
new file mode 100644 (file)
index 0000000..4a136b5
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright 2022 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 a
+
+type MarshalOptions struct {
+       *typedArshalers[MarshalOptions]
+}
+
+func Marshal(in interface{}) (out []byte, err error) {
+       return MarshalOptions{}.Marshal(in)
+}
+
+func (mo MarshalOptions) Marshal(in interface{}) (out []byte, err error) {
+       err = mo.MarshalNext(in)
+       return nil, err
+}
+
+func (mo MarshalOptions) MarshalNext(in interface{}) error {
+       a := new(arshaler)
+       a.marshal = func(MarshalOptions) error { return nil }
+       return a.marshal(mo)
+}
+
+type arshaler struct {
+       marshal func(MarshalOptions) error
+}
+
+type typedArshalers[Options any] struct {
+       m M
+}
+
+func (a *typedArshalers[Options]) lookup(fnc func(Options) error) (func(Options) error, bool) {
+       a.m.Load(nil)
+       return fnc, false
+}
+
+type M struct {}
+
+func (m *M) Load(key any) (value any, ok bool) {
+       return
+}
diff --git a/test/typeparam/issue50437.dir/b.go b/test/typeparam/issue50437.dir/b.go
new file mode 100644 (file)
index 0000000..afddc3f
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2022 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 b
+
+import "./a"
+
+func f() {
+       a.Marshal(map[int]int{})
+}
diff --git a/test/typeparam/issue50437.go b/test/typeparam/issue50437.go
new file mode 100644 (file)
index 0000000..87b4ff4
--- /dev/null
@@ -0,0 +1,7 @@
+// compiledir -G=3
+
+// Copyright 2021 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 ignored