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:
parent
ff7cfafc58
commit
c846ececde
|
|
@ -65,7 +65,6 @@ var (
|
||||||
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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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{}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue