1
0
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:
Alan Donovan 2013-07-08 17:33:51 -04:00
parent 1aa0484f4b
commit 8846992823
4 changed files with 25 additions and 24 deletions

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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) {