diff options
author | Robert Griesemer <gri@golang.org> | 2021-02-03 14:56:13 -0800 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2021-02-04 22:20:33 +0000 |
commit | 1ff2fdaaf189e0d7ec73bdbff72558363239f48b (patch) | |
tree | 42512eabd1fa092e171cc296c2d1cfad86ec6220 /src/cmd/compile/internal/types2/version.go | |
parent | 370e9f58432c51bf3d95308cdc7109e25cc141f6 (diff) | |
download | go-1ff2fdaaf189e0d7ec73bdbff72558363239f48b.tar.gz go-1ff2fdaaf189e0d7ec73bdbff72558363239f48b.zip |
[dev.typeparams] cmd/compile/internal/types2: add support for language version checking
Add the Config.Lang field which may be set to a Go version string,
such as "go1.12". This is a string rather than explicit semantic
version numbers (such as {1, 12}) for API robustness; a string
is more flexible should we need more or different information.
Add -lang flag to types2 package for use with (manual) testing
when running "go test -run Check$ -lang=... -files=...".
While changing flags, look for comma-separated (rather than space-
separated) files when providing the -file flag.
Check that numeric constant literals, signed shift counts are
accepted according to the selected language version.
Type alias declarations and overlapping embedded interfaces are
not yet checked.
Updates #31793.
Change-Id: I9ff238ed38a88f377eb2267dc3e8816b89a40635
Reviewed-on: https://go-review.googlesource.com/c/go/+/289509
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'src/cmd/compile/internal/types2/version.go')
-rw-r--r-- | src/cmd/compile/internal/types2/version.go | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/types2/version.go b/src/cmd/compile/internal/types2/version.go new file mode 100644 index 0000000000..cb497f048e --- /dev/null +++ b/src/cmd/compile/internal/types2/version.go @@ -0,0 +1,81 @@ +// Copyright 2021 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 types2 + +import ( + "cmd/compile/internal/syntax" + "fmt" + "regexp" + "strconv" + "strings" +) + +// langCompat reports an error if the representation of a numeric +// literal is not compatible with the current language version. +func (check *Checker) langCompat(lit *syntax.BasicLit) { + s := lit.Value + if len(s) <= 2 || check.allowVersion(check.pkg, 1, 13) { + return + } + // len(s) > 2 + if strings.Contains(s, "_") { + check.errorf(lit, "underscores in numeric literals requires go1.13 or later") + return + } + if s[0] != '0' { + return + } + radix := s[1] + if radix == 'b' || radix == 'B' { + check.errorf(lit, "binary literals requires go1.13 or later") + return + } + if radix == 'o' || radix == 'O' { + check.errorf(lit, "0o/0O-style octal literals requires go1.13 or later") + return + } + if lit.Kind != syntax.IntLit && (radix == 'x' || radix == 'X') { + check.errorf(lit, "hexadecimal floating-point literals requires go1.13 or later") + } +} + +// allowVersion reports whether the given package +// is allowed to use version major.minor. +func (check *Checker) allowVersion(pkg *Package, major, minor int) bool { + // We assume that imported packages have all been checked, + // so we only have to check for the local package. + if pkg != check.pkg { + return true + } + ma, mi := check.version.major, check.version.minor + return ma == 0 && mi == 0 || ma > major || ma == major && mi >= minor +} + +type version struct { + major, minor int +} + +// parseGoVersion parses a Go version string (such as "go1.12") +// and returns the version, or an error. If s is the empty +// string, the version is 0.0. +func parseGoVersion(s string) (v version, err error) { + if s == "" { + return + } + matches := goVersionRx.FindStringSubmatch(s) + if matches == nil { + err = fmt.Errorf(`should be something like "go1.12"`) + return + } + v.major, err = strconv.Atoi(matches[1]) + if err != nil { + return + } + v.minor, err = strconv.Atoi(matches[2]) + return +} + +// goVersionRx matches a Go version string, e.g. "go1.12". +var goVersionRx = regexp.MustCompile(`^go([1-9][0-9]*)\.(0|[1-9][0-9]*)$`) |