mirror of
https://github.com/golang/go.git
synced 2025-05-05 23:53:05 +00:00
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:
parent
66f0d6e92e
commit
78c8226b42
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
5
go/types/testdata/shifts.src
vendored
5
go/types/testdata/shifts.src
vendored
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user