From 92c732e901a732855f4b813e6676264421eceae9 Mon Sep 17 00:00:00 2001 From: David Chase Date: Fri, 13 Nov 2020 16:54:48 -0500 Subject: [PATCH] cmd/compile: fix load of interface{}-typed OpIData in expand_calls In certain cases, the declkared type of an OpIData is interface{}. This was not expected (since interface{} is a pair, right?) and thus caused a crash. What is intended is that these be treated as a byteptr, so do that instead (this is what happens in 1.15). Fixes #42568. Change-Id: Id7c9e5dc2cbb5d7c71c6748832491ea62b0b339f Reviewed-on: https://go-review.googlesource.com/c/go/+/270057 Trust: David Chase Run-TryBot: David Chase Reviewed-by: Cuong Manh Le --- src/cmd/compile/internal/amd64/ssa.go | 4 ++-- src/cmd/compile/internal/ssa/expand_calls.go | 3 +++ test/fixedbugs/issue42568.go | 25 ++++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 test/fixedbugs/issue42568.go diff --git a/src/cmd/compile/internal/amd64/ssa.go b/src/cmd/compile/internal/amd64/ssa.go index 76e33a3689..5ff05a0edd 100644 --- a/src/cmd/compile/internal/amd64/ssa.go +++ b/src/cmd/compile/internal/amd64/ssa.go @@ -76,7 +76,7 @@ func storeByType(t *types.Type) obj.As { return x86.AMOVQ } } - panic("bad store type") + panic(fmt.Sprintf("bad store type %v", t)) } // moveByType returns the reg->reg move instruction of the given type. @@ -101,7 +101,7 @@ func moveByType(t *types.Type) obj.As { case 16: return x86.AMOVUPS // int128s are in SSE registers default: - panic(fmt.Sprintf("bad int register width %d:%s", t.Size(), t)) + panic(fmt.Sprintf("bad int register width %d:%v", t.Size(), t)) } } } diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go index fbde19d94c..3681af6599 100644 --- a/src/cmd/compile/internal/ssa/expand_calls.go +++ b/src/cmd/compile/internal/ssa/expand_calls.go @@ -196,6 +196,9 @@ func expandCalls(f *Func) { } if leaf.Op == OpIData { leafType = removeTrivialWrapperTypes(leaf.Type) + if leafType.IsEmptyInterface() { + leafType = typ.BytePtr + } } aux := selector.Aux auxInt := selector.AuxInt + offset diff --git a/test/fixedbugs/issue42568.go b/test/fixedbugs/issue42568.go new file mode 100644 index 0000000000..834fdc58f3 --- /dev/null +++ b/test/fixedbugs/issue42568.go @@ -0,0 +1,25 @@ +// compile + +// Copyright 2020 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. + +// Ensure that late expansion correctly handles an OpIData with type interface{} + +package p + +type S struct{} + +func (S) M() {} + +type I interface { + M() +} + +func f(i I) { + o := i.(interface{}) + if _, ok := i.(*S); ok { + o = nil + } + println(o) +}