cmd/compile: do not reuse dead value in expand_calls pass

We reuse a value for the same selector on the same arg. But if the
value is already marked dead, don't reuse it. A use of an
OpInvalid will confuse the compiler.

Fixes #48916.

Change-Id: I15b9e15b49f6e1991fe91df246cd12a193385e85
Reviewed-on: https://go-review.googlesource.com/c/go/+/355409
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
Cherry Mui 2021-10-12 12:38:42 -04:00
parent 36a265a625
commit 6e0adde1e9
2 changed files with 45 additions and 2 deletions

View file

@ -1678,7 +1678,7 @@ func (x *expandState) rewriteArgToMemOrRegs(v *Value) *Value {
t := v.Type
key := selKey{v, 0, t.Size(), t}
w := x.commonArgs[key]
if w != nil {
if w != nil && w.Uses != 0 { // do not reuse dead value
v.copyOf(w)
break
}
@ -1709,9 +1709,15 @@ func (x *expandState) newArgToMemOrRegs(baseArg, toReplace *Value, offset int64,
}
key := selKey{baseArg, offset, t.Size(), t}
w := x.commonArgs[key]
if w != nil {
if w != nil && w.Uses != 0 { // do not reuse dead value
if toReplace != nil {
toReplace.copyOf(w)
if x.debug > 1 {
x.Printf("...replace %s\n", toReplace.LongString())
}
}
if x.debug > 1 {
x.Printf("-->%s\n", w.LongString())
}
return w
}

View file

@ -0,0 +1,37 @@
// 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.
// Issue 48916: expand_calls pass crashes due to a (dead)
// use of an OpInvalid value.
package p
type T struct {
num int64
}
func foo(vs map[T]struct{}, d T) error {
_, ok := vs[d]
if !ok {
return nil
}
switch d.num {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
var num float64
if num != 0 {
return nil
}
}
return nil
}