From 8a12f5d6e886962fb366cd58c5669001e2790885 Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Fri, 5 Nov 2021 20:30:38 +0700 Subject: [release-branch.go1.16] cmd/compile: only update source type when processing struct/array This is backport of CL 3651594, with the test from CL 360057. CL 360057 fixed missing update source type in storeArgOrLoad. However, we should only update the type when processing struct/array. If we update the type right before calling storeArgOrLoad, we may generate a value with invalid type, e.g, OpStructSelect with non-struct type. Fixes #49391 Change-Id: Ib7e10f72f818880f550aae5c9f653db463ce29b0 Reviewed-on: https://go-review.googlesource.com/c/go/+/361594 Trust: Cuong Manh Le Run-TryBot: Cuong Manh Le TryBot-Result: Go Bot Reviewed-by: David Chase Reviewed-on: https://go-review.googlesource.com/c/go/+/361597 TryBot-Result: Gopher Robot Reviewed-by: Keith Randall --- src/cmd/compile/internal/ssa/expand_calls.go | 2 + test/fixedbugs/issue49249.go | 55 ++++++++++++++++++++++++++++ test/fixedbugs/issue49378.go | 25 +++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 test/fixedbugs/issue49249.go create mode 100644 test/fixedbugs/issue49378.go diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go index 679ee8ad16..e06ed882f0 100644 --- a/src/cmd/compile/internal/ssa/expand_calls.go +++ b/src/cmd/compile/internal/ssa/expand_calls.go @@ -527,6 +527,7 @@ func expandCalls(f *Func) { // it could be a leaf type, but the "leaf" could be complex64 (for example) return storeArgOrLoad(pos, b, base, source, mem, t, offset) } + source.Type = t for i := int64(0); i < t.NumElem(); i++ { sel := source.Block.NewValue1I(pos, OpArraySelect, elt, i, source) mem = storeArgOrLoad(pos, b, base, sel, mem, elt, offset+i*elt.Width) @@ -559,6 +560,7 @@ func expandCalls(f *Func) { return storeArgOrLoad(pos, b, base, source, mem, t, offset) } + source.Type = t for i := 0; i < t.NumFields(); i++ { fld := t.Field(i) sel := source.Block.NewValue1I(pos, OpStructSelect, fld.Type, int64(i), source) diff --git a/test/fixedbugs/issue49249.go b/test/fixedbugs/issue49249.go new file mode 100644 index 0000000000..f152a5a701 --- /dev/null +++ b/test/fixedbugs/issue49249.go @@ -0,0 +1,55 @@ +// compile -l + +// 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 p + +func f() int { + var a, b struct { + s struct { + s struct { + byte + float32 + } + } + } + _ = a + + return func() int { + return func() int { + a = struct { + s struct { + s struct { + byte + float32 + } + } + }{b.s} + return 0 + }() + }() +} + +func g() int { + var a, b struct { + s [1][1]struct { + byte + float32 + } + } + _ = a + + return func() int { + return func() int { + a = struct { + s [1][1]struct { + byte + float32 + } + }{b.s} + return 0 + }() + }() +} diff --git a/test/fixedbugs/issue49378.go b/test/fixedbugs/issue49378.go new file mode 100644 index 0000000000..70f466c929 --- /dev/null +++ b/test/fixedbugs/issue49378.go @@ -0,0 +1,25 @@ +// compile + +// 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 p + +func f(i int) { + var s1 struct { + s struct{ s struct{ i int } } + } + var s2, s3 struct { + a struct{ i int } + b int + } + func() { + i = 1 + 2*i + s3.a.i + func() int { + s2.a, s2.b = s3.a, s3.b + return 0 + }() + func(*int) int { + return s1.s.s.i + }(new(int)) + }() +} -- cgit v1.2.3-54-g00ecf