go.tools/ssa: eliminate remaining uses of operands of "untyped" type.

Added sanity check.

R=gri
CC=golang-dev
https://golang.org/cl/37270043
This commit is contained in:
Alan Donovan 2013-12-04 13:59:55 -05:00
parent ff7cfafc58
commit c846ececde
4 changed files with 20 additions and 9 deletions

View File

@ -62,10 +62,9 @@ var (
tEface = new(types.Interface) tEface = new(types.Interface)
// SSA Value constants. // SSA Value constants.
vZero = intConst(0) vZero = intConst(0)
vOne = intConst(1) vOne = intConst(1)
vTrue = NewConst(exact.MakeBool(true), tBool) vTrue = NewConst(exact.MakeBool(true), tBool)
vFalse = NewConst(exact.MakeBool(false), tBool)
) )
// builder holds state associated with the package currently being built. // builder holds state associated with the package currently being built.
@ -314,7 +313,7 @@ func (b *builder) builtin(fn *Function, obj *types.Builtin, args []ast.Expr, typ
pos: pos, pos: pos,
}) })
fn.currentBlock = fn.newBasicBlock("unreachable") fn.currentBlock = fn.newBasicBlock("unreachable")
return vFalse // any non-nil Value will do return vTrue // any non-nil Value will do
} }
return nil // treat all others as a regular function call return nil // treat all others as a regular function call
} }
@ -1890,7 +1889,8 @@ start:
if s.Tok == token.DEC { if s.Tok == token.DEC {
op = token.SUB op = token.SUB
} }
b.assignOp(fn, b.addr(fn, s.X, false), vOne, op) loc := b.addr(fn, s.X, false)
b.assignOp(fn, loc, NewConst(exact.MakeInt64(1), loc.typ()), op)
case *ast.AssignStmt: case *ast.AssignStmt:
switch s.Tok { switch s.Tok {

View File

@ -22,9 +22,10 @@ func NewConst(val exact.Value, typ types.Type) *Const {
return &Const{typ, val} return &Const{typ, val}
} }
// intConst returns an untyped integer constant that evaluates to i. // intConst returns an 'int' constant that evaluates to i.
// (i is an int64 in case the host is narrower than the target.)
func intConst(i int64) *Const { func intConst(i int64) *Const {
return NewConst(exact.MakeInt64(i), types.Typ[types.UntypedInt]) return NewConst(exact.MakeInt64(i), types.Typ[types.Int])
} }
// nilConst returns a nil constant of the specified type, which may // nilConst returns a nil constant of the specified type, which may

View File

@ -101,7 +101,7 @@ func main() {
// func main(): // func main():
// .0.entry: P:0 S:0 // .0.entry: P:0 S:0
// t0 = new [1]interface{} (varargs) *[1]interface{} // t0 = new [1]interface{} (varargs) *[1]interface{}
// t1 = &t0[0:untyped integer] *interface{} // t1 = &t0[0:int] *interface{}
// t2 = make interface{} <- string ("Hello, World!":string) interface{} // t2 = make interface{} <- string ("Hello, World!":string) interface{}
// *t1 = t2 // *t1 = t2
// t3 = slice t0[:] []interface{} // t3 = slice t0[:] []interface{}

View File

@ -325,6 +325,16 @@ func (s *sanity) checkBlock(b *BasicBlock, index int) {
if val == nil { if val == nil {
continue // a nil operand is ok continue // a nil operand is ok
} }
// Check that "untyped" types only appear on constant operands.
if _, ok := (*op).(*Const); !ok {
if basic, ok := (*op).Type().(*types.Basic); ok {
if basic.Info()&types.IsUntyped != 0 {
s.errorf("operand #%d of %s is untyped: %s", i, instr, basic)
}
}
}
// Check that Operands that are also Instructions belong to same function. // Check that Operands that are also Instructions belong to same function.
// TODO(adonovan): also check their block dominates block b. // TODO(adonovan): also check their block dominates block b.
if val, ok := val.(Instruction); ok { if val, ok := val.(Instruction); ok {