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
}
if *listErrors {
if *listErrors && len(errlist) > 0 {
t.Errorf("--- %s:", pkgName)
for _, err := range errlist {
t.Error(err)

View File

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

View File

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