mirror of
https://github.com/golang/go.git
synced 2024-09-22 02:48:50 +00:00
go/types: don't report errors for untyped int shifts on Go < 1.13
CL 337529 introduced upfront type-checking of constant shift operands, to avoid converting their type to uint (per the spec). However, it had an oversight in that the checks intended for non-constant operands still ran after the explicit checking of constant operands. As a result, there are at least two bugs: - When GoVersion is < 1.13, we report spurious errors for untyped constant shift operands. - When the operand is an untyped float constant, we still convert to uint (this was a known bug reported in #47410). Looking at this now, it seems clear that we can avoid both of these bugs by simply not running the additional checks in the case of a constant operand. However, this should be considered with some care, as shifts are notoriously tricky. Updates #47410 Fixes #52031 Change-Id: Ia489cc5470b92a8187d3de0423d05b309daf47bb Reviewed-on: https://go-review.googlesource.com/c/go/+/396775 Reviewed-by: Robert Griesemer <gri@golang.org> Trust: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
f8e70fc9a6
commit
8a816d5efc
@ -330,7 +330,7 @@ func TestTypesInfo(t *testing.T) {
|
||||
|
||||
// issue 47243
|
||||
{`package issue47243_a; var x int32; var _ = x << 3`, `3`, `untyped int`},
|
||||
{`package issue47243_b; var x int32; var _ = x << 3.`, `3.`, `uint`}, // issue 47410: should be untyped float
|
||||
{`package issue47243_b; var x int32; var _ = x << 3.`, `3.`, `untyped float`},
|
||||
{`package issue47243_c; var x int32; var _ = 1 << x`, `1 << x`, `int`},
|
||||
{`package issue47243_d; var x int32; var _ = 1 << x`, `1`, `int`},
|
||||
{`package issue47243_e; var x int32; var _ = 1 << 2`, `1`, `untyped int`},
|
||||
|
@ -235,6 +235,11 @@ func testFiles(t *testing.T, sizes Sizes, filenames []string, srcs [][]byte, man
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if manual && *goVersion != "" {
|
||||
// goVersion overrides -lang for manual tests.
|
||||
conf.GoVersion = *goVersion
|
||||
}
|
||||
|
||||
// TODO(gri) remove this or use flag mechanism to set mode if still needed
|
||||
if strings.HasSuffix(filenames[0], ".go1") {
|
||||
// TODO(rfindley): re-enable this test by using GoVersion.
|
||||
|
@ -934,28 +934,28 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that RHS is otherwise at least of integer type.
|
||||
switch {
|
||||
case allInteger(y.typ):
|
||||
if !allUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) {
|
||||
check.invalidOp(y, _InvalidShiftCount, "signed shift count %s requires go1.13 or later", y)
|
||||
} else {
|
||||
// Check that RHS is otherwise at least of integer type.
|
||||
switch {
|
||||
case allInteger(y.typ):
|
||||
if !allUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) {
|
||||
check.invalidOp(y, _InvalidShiftCount, "signed shift count %s requires go1.13 or later", y)
|
||||
x.mode = invalid
|
||||
return
|
||||
}
|
||||
case isUntyped(y.typ):
|
||||
// This is incorrect, but preserves pre-existing behavior.
|
||||
// See also bug #47410.
|
||||
check.convertUntyped(y, Typ[Uint])
|
||||
if y.mode == invalid {
|
||||
x.mode = invalid
|
||||
return
|
||||
}
|
||||
default:
|
||||
check.invalidOp(y, _InvalidShiftCount, "shift count %s must be integer", y)
|
||||
x.mode = invalid
|
||||
return
|
||||
}
|
||||
case isUntyped(y.typ):
|
||||
// This is incorrect, but preserves pre-existing behavior.
|
||||
// See also bug #47410.
|
||||
check.convertUntyped(y, Typ[Uint])
|
||||
if y.mode == invalid {
|
||||
x.mode = invalid
|
||||
return
|
||||
}
|
||||
default:
|
||||
check.invalidOp(y, _InvalidShiftCount, "shift count %s must be integer", y)
|
||||
x.mode = invalid
|
||||
return
|
||||
}
|
||||
|
||||
if x.mode == constant_ {
|
||||
|
33
src/go/types/testdata/fixedbugs/issue52031.go
vendored
Normal file
33
src/go/types/testdata/fixedbugs/issue52031.go
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
// -lang=go1.12
|
||||
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package p
|
||||
|
||||
type resultFlags uint
|
||||
|
||||
// Example from #52031.
|
||||
//
|
||||
// The following shifts should not produce errors on Go < 1.13, as their
|
||||
// untyped constant operands are representable by type uint.
|
||||
const (
|
||||
_ resultFlags = (1 << iota) / 2
|
||||
|
||||
reportEqual
|
||||
reportUnequal
|
||||
reportByIgnore
|
||||
reportByMethod
|
||||
reportByFunc
|
||||
reportByCycle
|
||||
)
|
||||
|
||||
// Invalid cases.
|
||||
var x int = 1
|
||||
var _ = (8 << x /* ERROR "signed shift count .* requires go1.13 or later" */)
|
||||
|
||||
const _ = (1 << 1.2 /* ERROR "truncated to uint" */)
|
||||
|
||||
var y float64
|
||||
var _ = (1 << y /* ERROR "must be integer" */)
|
Loading…
Reference in New Issue
Block a user