diff --git a/ssa/builder.go b/ssa/builder.go index 2686f9cb..69c9869a 100644 --- a/ssa/builder.go +++ b/ssa/builder.go @@ -62,10 +62,9 @@ var ( tEface = new(types.Interface) // SSA Value constants. - vZero = intConst(0) - vOne = intConst(1) - vTrue = NewConst(exact.MakeBool(true), tBool) - vFalse = NewConst(exact.MakeBool(false), tBool) + vZero = intConst(0) + vOne = intConst(1) + vTrue = NewConst(exact.MakeBool(true), tBool) ) // 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, }) 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 } @@ -1890,7 +1889,8 @@ start: if s.Tok == token.DEC { 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: switch s.Tok { diff --git a/ssa/const.go b/ssa/const.go index 5083d997..4b84be8c 100644 --- a/ssa/const.go +++ b/ssa/const.go @@ -22,9 +22,10 @@ func NewConst(val exact.Value, typ types.Type) *Const { 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 { - 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 diff --git a/ssa/example_test.go b/ssa/example_test.go index 520f47d9..44c44a3f 100644 --- a/ssa/example_test.go +++ b/ssa/example_test.go @@ -101,7 +101,7 @@ func main() { // func main(): // .0.entry: P:0 S:0 // 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{} // *t1 = t2 // t3 = slice t0[:] []interface{} diff --git a/ssa/sanity.go b/ssa/sanity.go index 9b5bb68a..18bfa8bc 100644 --- a/ssa/sanity.go +++ b/ssa/sanity.go @@ -325,6 +325,16 @@ func (s *sanity) checkBlock(b *BasicBlock, index int) { if val == nil { 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. // TODO(adonovan): also check their block dominates block b. if val, ok := val.(Instruction); ok {