go.tools/go/types: don't modify lhs untyped types in constant shifts

Also: fix TestCheck (don't fail if there are no errors in -list mode)

Fixes golang/go#5895.

R=adonovan
CC=golang-dev
https://golang.org/cl/11535043
This commit is contained in:
Robert Griesemer 2013-07-18 10:48:03 -07:00
parent 66f0d6e92e
commit 78c8226b42
3 changed files with 15 additions and 18 deletions

View File

@ -195,7 +195,7 @@ func checkFiles(t *testing.T, testfiles []string) {
pkgName = files[0].Name.Name pkgName = files[0].Name.Name
} }
if *listErrors { if *listErrors && len(errlist) > 0 {
t.Errorf("--- %s:", pkgName) t.Errorf("--- %s:", pkgName)
for _, err := range errlist { for _, err := range errlist {
t.Error(err) t.Error(err)

View File

@ -540,9 +540,6 @@ func (check *checker) shift(x, y *operand, op token.Token) {
if x.mode == constant { if x.mode == constant {
if y.mode == constant { if y.mode == constant {
if untypedx {
x.typ = Typ[UntypedInt]
}
// rhs must be within reasonable bounds // rhs must be within reasonable bounds
const stupidShift = 1024 const stupidShift = 1024
s, ok := exact.Uint64Val(y.val) s, ok := exact.Uint64Val(y.val)
@ -558,22 +555,18 @@ func (check *checker) shift(x, y *operand, op token.Token) {
// non-constant shift with constant lhs // non-constant shift with constant lhs
if untypedx { if untypedx {
// spec: "If the left operand of a non-constant shift expression is // spec: "If the left operand of a non-constant shift
// an untyped constant, the type of the constant is what it would be // expression is an untyped constant, the type of the
// if the shift expression were replaced by its left operand alone; // constant is what it would be if the shift expression
// the type is int if it cannot be determined from the context (for // were replaced by its left operand alone.".
// instance, if the shift expression is an operand in a comparison //
// against an untyped constant)".
// Delay operand checking until we know the final type: // Delay operand checking until we know the final type:
// The lhs expression must be in the untyped map, mark // The lhs expression must be in the untyped map, mark
// the entry as lhs shift operand. // the entry as lhs shift operand.
if info, ok := check.untyped[x.expr]; ok { info, found := check.untyped[x.expr]
assert(found)
info.isLhs = true info.isLhs = true
check.untyped[x.expr] = info check.untyped[x.expr] = info
} else {
unreachable()
}
// keep x's type // keep x's type
x.mode = value x.mode = value
return return
@ -587,7 +580,6 @@ func (check *checker) shift(x, y *operand, op token.Token) {
return return
} }
// non-constant shift
x.mode = value x.mode = value
} }

View File

@ -291,3 +291,8 @@ func shifts9() {
for s.Whitespace&(1<<uint(ch)) != 0 {} for s.Whitespace&(1<<uint(ch)) != 0 {}
} }
} }
func issue5895() {
var x = 'a' << 1 // type of x must be rune
var _ rune = x
}