aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/types2/version.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2021-02-03 14:56:13 -0800
committerRobert Griesemer <gri@golang.org>2021-02-04 22:20:33 +0000
commit1ff2fdaaf189e0d7ec73bdbff72558363239f48b (patch)
tree42512eabd1fa092e171cc296c2d1cfad86ec6220 /src/cmd/compile/internal/types2/version.go
parent370e9f58432c51bf3d95308cdc7109e25cc141f6 (diff)
downloadgo-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.go81
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]*)$`)