go/ssa: fix crash when building map[*struct{}]bool{{}: true}
Since Go 1.5, if a key expression in a map literal is itself a composite literal, the type may be omitted. An & operation may be implied, but was not generated, resulting in a type mismatch crash. Added regression test. Also, added missing intrinsic math.hasSSE4 to interpreter. Fixes issue 13341 Change-Id: I6a5e560460cdcac295a500a3fc3738cbe8aa5853 Reviewed-on: https://go-review.googlesource.com/17123 Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
9cd799205e
commit
977844c7af
|
@ -1194,9 +1194,26 @@ func (b *builder) compLit(fn *Function, addr Value, e *ast.CompositeLit, isZero
|
|||
fn.emit(m)
|
||||
for _, e := range e.Elts {
|
||||
e := e.(*ast.KeyValueExpr)
|
||||
|
||||
// If a key expression in a map literal is itself a
|
||||
// composite literal, the type may be omitted.
|
||||
// For example:
|
||||
// map[*struct{}]bool{{}: true}
|
||||
// An &-operation may be implied:
|
||||
// map[*struct{}]bool{&struct{}{}: true}
|
||||
var key Value
|
||||
if _, ok := unparen(e.Key).(*ast.CompositeLit); ok && isPointer(t.Key()) {
|
||||
// A CompositeLit never evaluates to a pointer,
|
||||
// so if the type of the location is a pointer,
|
||||
// an &-operation is implied.
|
||||
key = b.addr(fn, e.Key, true).address(fn)
|
||||
} else {
|
||||
key = b.expr(fn, e.Key)
|
||||
}
|
||||
|
||||
loc := element{
|
||||
m: m,
|
||||
k: emitConv(fn, b.expr(fn, e.Key), t.Key()),
|
||||
k: emitConv(fn, key, t.Key()),
|
||||
t: t.Elem(),
|
||||
pos: e.Colon,
|
||||
}
|
||||
|
|
|
@ -80,6 +80,7 @@ func init() {
|
|||
"math.Ldexp": ext۰math۰Ldexp,
|
||||
"math.Log": ext۰math۰Log,
|
||||
"math.Min": ext۰math۰Min,
|
||||
"math.hasSSE4": ext۰math۰hasSSE4,
|
||||
"os.runtime_args": ext۰os۰runtime_args,
|
||||
"os.runtime_beforeExit": ext۰os۰runtime_beforeExit,
|
||||
"reflect.New": ext۰reflect۰New,
|
||||
|
@ -220,6 +221,10 @@ func ext۰math۰Min(fr *frame, args []value) value {
|
|||
return math.Min(args[0].(float64), args[1].(float64))
|
||||
}
|
||||
|
||||
func ext۰math۰hasSSE4(fr *frame, args []value) value {
|
||||
return false
|
||||
}
|
||||
|
||||
func ext۰math۰Ldexp(fr *frame, args []value) value {
|
||||
return math.Ldexp(args[0].(float64), args[1].(int))
|
||||
}
|
||||
|
|
|
@ -164,5 +164,21 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
// Regression test for https://github.com/golang/go/issues/13341:
|
||||
// within a map literal, if a key expression is a composite literal,
|
||||
// Go 1.5 allows its type to be omitted. An & operation may be implied.
|
||||
func init() {
|
||||
type S struct{ x int }
|
||||
// same as map[*S]bool{&S{x: 1}: true}
|
||||
m := map[*S]bool{{x: 1}: true}
|
||||
for s := range m {
|
||||
if s.x != 1 {
|
||||
panic(s) // wrong key
|
||||
}
|
||||
return
|
||||
}
|
||||
panic("map is empty")
|
||||
}
|
||||
|
||||
func main() {
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue