mirror of
https://github.com/golang/go
synced 2024-10-01 03:38:32 -06:00
go.tools/ssa: avoid redundant uint64 conversion of right operand of <<, >>.
Also: add sanity check that no Instruction yields a Value of 'untyped' type. R=golang-dev, gri CC=golang-dev https://golang.org/cl/11011043
This commit is contained in:
parent
1aa0484f4b
commit
8846992823
@ -38,7 +38,6 @@ func emitArith(f *Function, op token.Token, x, y Value, t types.Type, pos token.
|
||||
switch op {
|
||||
case token.SHL, token.SHR:
|
||||
x = emitConv(f, x, t)
|
||||
y = emitConv(f, y, types.Typ[types.Uint64])
|
||||
|
||||
case token.ADD, token.SUB, token.MUL, token.QUO, token.REM, token.AND, token.OR, token.XOR, token.AND_NOT:
|
||||
x = emitConv(f, x, t)
|
||||
|
@ -130,26 +130,6 @@ func asInt(x value) int {
|
||||
panic(fmt.Sprintf("cannot convert %T to int", x))
|
||||
}
|
||||
|
||||
// asUint64 converts x, which must be an unsigned integer, to a uint64
|
||||
// suitable for use as a bitwise shift count.
|
||||
func asUint64(x value) uint64 {
|
||||
switch x := x.(type) {
|
||||
case uint:
|
||||
return uint64(x)
|
||||
case uint8:
|
||||
return uint64(x)
|
||||
case uint16:
|
||||
return uint64(x)
|
||||
case uint32:
|
||||
return uint64(x)
|
||||
case uint64:
|
||||
return x
|
||||
case uintptr:
|
||||
return uint64(x)
|
||||
}
|
||||
panic(fmt.Sprintf("cannot convert %T to uint64", x))
|
||||
}
|
||||
|
||||
// zero returns a new "zero" value of the specified type.
|
||||
func zero(t types.Type) value {
|
||||
switch t := t.(type) {
|
||||
@ -563,7 +543,7 @@ func binop(op token.Token, x, y value) value {
|
||||
}
|
||||
|
||||
case token.SHL:
|
||||
y := asUint64(y)
|
||||
y := uint64(asInt(y))
|
||||
switch x.(type) {
|
||||
case int:
|
||||
return x.(int) << y
|
||||
@ -590,7 +570,7 @@ func binop(op token.Token, x, y value) value {
|
||||
}
|
||||
|
||||
case token.SHR:
|
||||
y := asUint64(y)
|
||||
y := uint64(asInt(y))
|
||||
switch x.(type) {
|
||||
case int:
|
||||
return x.(int) >> y
|
||||
|
10
ssa/interp/testdata/coverage.go
vendored
10
ssa/interp/testdata/coverage.go
vendored
@ -270,6 +270,16 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
type mybool bool
|
||||
|
||||
func (mybool) f() {}
|
||||
|
||||
func init() {
|
||||
var x, y int
|
||||
var b mybool = x == y // x==y is an untyped bool
|
||||
b.f()
|
||||
}
|
||||
|
||||
// Simple closures.
|
||||
func init() {
|
||||
b := 3
|
||||
|
@ -160,11 +160,23 @@ func (s *sanity) checkInstr(idx int, instr Instruction) {
|
||||
panic(fmt.Sprintf("Unknown instruction type: %T", instr))
|
||||
}
|
||||
|
||||
// Check that value-defining instructions have valid types.
|
||||
if v, ok := instr.(Value); ok {
|
||||
if v.Type() == nil {
|
||||
t := v.Type()
|
||||
if t == nil {
|
||||
s.errorf("no type: %s = %s", v.Name(), v)
|
||||
} else if t == tRangeIter {
|
||||
// not a proper type; ignore.
|
||||
} else if b, ok := t.Underlying().(*types.Basic); ok && b.Info()&types.IsUntyped != 0 {
|
||||
s.errorf("instruction has 'untyped' result: %s = %s : %s", v.Name(), v, t)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(adonovan): sanity-check Literals used as instruction Operands(),
|
||||
// e.g. reject Literals with "untyped" types.
|
||||
//
|
||||
// All other non-Instruction Values can be found via their
|
||||
// enclosing Function or Package.
|
||||
}
|
||||
|
||||
func (s *sanity) checkFinalInstr(idx int, instr Instruction) {
|
||||
|
Loading…
Reference in New Issue
Block a user