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
|
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)
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {}
|
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