Commit febafe60 authored by David Chase's avatar David Chase

cmd/compile: added cheapexpr call to simplify operand of CONVIFACE

New special case for booleans and byte-sized integer types
converted to interfaces needs to ensure that the operand is
not too complex, if it were to appear in a parameter list
for example.

Added test, also increased the recursive node dump depth to
a level that was actually useful for an actual bug.

Fixes #19275.

Change-Id: If36ac3115edf439e886703f32d149ee0a46eb2a5
Reviewed-on: https://go-review.googlesource.com/37470
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarJosh Bleecher Snyder <josharian@gmail.com>
parent ac91a514
...@@ -1486,7 +1486,7 @@ func (n *Node) nodedump(s fmt.State, flag FmtFlag) { ...@@ -1486,7 +1486,7 @@ func (n *Node) nodedump(s fmt.State, flag FmtFlag) {
if recur { if recur {
indent(s) indent(s)
if dumpdepth > 10 { if dumpdepth > 40 {
fmt.Fprint(s, "...") fmt.Fprint(s, "...")
return return
} }
......
...@@ -886,6 +886,7 @@ opswitch: ...@@ -886,6 +886,7 @@ opswitch:
value = zerobase value = zerobase
case n.Left.Type.IsBoolean() || (n.Left.Type.Size() == 1 && n.Left.Type.IsInteger()): case n.Left.Type.IsBoolean() || (n.Left.Type.Size() == 1 && n.Left.Type.IsInteger()):
// n.Left is a bool/byte. Use staticbytes[n.Left]. // n.Left is a bool/byte. Use staticbytes[n.Left].
n.Left = cheapexpr(n.Left, init)
value = nod(OINDEX, staticbytes, byteindex(n.Left)) value = nod(OINDEX, staticbytes, byteindex(n.Left))
value.Bounded = true value.Bounded = true
case n.Left.Class == PEXTERN && n.Left.Name != nil && n.Left.Name.Readonly: case n.Left.Class == PEXTERN && n.Left.Name != nil && n.Left.Name.Readonly:
......
// run
// Copyright 2017 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 main
import (
"fmt"
)
type PI struct {
Enabled bool
}
type SI struct {
M map[string]*PI
}
//go:noinline
func (s *SI) test(name string) (*int, error) {
n := new(int)
*n = 99
if err := addUpdate(n, s.M[name].Enabled, "enabled"); err != nil { // this was miscompiled
return nil, fmt.Errorf(" error adding update for enable flag %t : %s",
s.M[name].Enabled, err)
}
return n, nil
}
//go:noinline
func addUpdate(n *int, in interface{}, s ...string) error {
if *n != 99 {
println("FAIL, *n should be 99, not", *n)
}
return nil
}
func main1() {
s := &SI{make(map[string]*PI)}
s.M["dog"] = &PI{}
s.test("dog")
}
//go:noinline
func g(b *byte, i interface{}) error {
if *b != 17 {
println("FAIL, *b should be 17, not", *b)
}
return nil
}
//go:noinline
func f(x *byte, m map[string]*bool) {
if err := g(x, *m["hello"]); err != nil { // this was miscompiled
return
}
}
func main2() {
m := make(map[string]*bool)
x := false
m["hello"] = &x
b := byte(17)
f(&b, m)
}
func main() {
main2()
main1()
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment