diff options
| author | Alan Donovan <adonovan@google.com> | 2025-09-17 22:17:41 -0400 |
|---|---|---|
| committer | Alan Donovan <adonovan@google.com> | 2025-09-23 11:36:46 -0700 |
| commit | a27261c42fcebf601587725714b9ef53c47b06b3 (patch) | |
| tree | 2f584ab21e11369633139c3c8f5752779a68bafa /src | |
| parent | e93f439ac4160baf9992f059d2bfb511e23f63c9 (diff) | |
| download | go-a27261c42fcebf601587725714b9ef53c47b06b3.tar.xz | |
go/types,types2: allow new(expr)
For #45624
Change-Id: I6d77a2a1d6095cac0edc36060cbf98c72b749404
Reviewed-on: https://go-review.googlesource.com/c/go/+/704935
Auto-Submit: Alan Donovan <adonovan@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/compile/internal/types2/builtins.go | 27 | ||||
| -rw-r--r-- | src/cmd/compile/internal/types2/version.go | 1 | ||||
| -rw-r--r-- | src/go/types/builtins.go | 27 | ||||
| -rw-r--r-- | src/go/types/version.go | 1 | ||||
| -rw-r--r-- | src/internal/types/testdata/check/builtins0.go | 46 | ||||
| -rw-r--r-- | src/internal/types/testdata/check/go1_25.go | 13 | ||||
| -rw-r--r-- | src/internal/types/testdata/fixedbugs/issue43125.go | 8 |
7 files changed, 96 insertions, 27 deletions
diff --git a/src/cmd/compile/internal/types2/builtins.go b/src/cmd/compile/internal/types2/builtins.go index 4bb2135755..3de2857ed4 100644 --- a/src/cmd/compile/internal/types2/builtins.go +++ b/src/cmd/compile/internal/types2/builtins.go @@ -636,11 +636,30 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) ( } case _New: - // new(T) + // new(T) or new(expr) // (no argument evaluated yet) - T := check.varType(argList[0]) - if !isValid(T) { - return + arg := argList[0] + check.exprOrType(x, arg, true) + var T Type + switch x.mode { + case builtin: + check.errorf(x, UncalledBuiltin, "%s must be called", x) + x.mode = invalid + case typexpr: + // new(T) + T = x.typ + if !isValid(T) { + return + } + default: + // new(expr) + check.verifyVersionf(call.Fun, go1_26, "new(expr)") + T = Default(x.typ) + if T != x.typ { + // untyped constant: check for overflow. + check.assignment(x, T, "argument to new") + } + check.validVarType(arg, T) } x.mode = value diff --git a/src/cmd/compile/internal/types2/version.go b/src/cmd/compile/internal/types2/version.go index b555f398da..765b0f7e9a 100644 --- a/src/cmd/compile/internal/types2/version.go +++ b/src/cmd/compile/internal/types2/version.go @@ -43,6 +43,7 @@ var ( go1_21 = asGoVersion("go1.21") go1_22 = asGoVersion("go1.22") go1_23 = asGoVersion("go1.23") + go1_26 = asGoVersion("go1.26") // current (deployed) Go version go_current = asGoVersion(fmt.Sprintf("go1.%d", goversion.Version)) diff --git a/src/go/types/builtins.go b/src/go/types/builtins.go index e9f2b3e21d..1163321ecd 100644 --- a/src/go/types/builtins.go +++ b/src/go/types/builtins.go @@ -639,11 +639,30 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b } case _New: - // new(T) + // new(T) or new(expr) // (no argument evaluated yet) - T := check.varType(argList[0]) - if !isValid(T) { - return + arg := argList[0] + check.exprOrType(x, arg, true) + var T Type + switch x.mode { + case builtin: + check.errorf(x, UncalledBuiltin, "%s must be called", x) + x.mode = invalid + case typexpr: + // new(T) + T = x.typ + if !isValid(T) { + return + } + default: + // new(expr) + check.verifyVersionf(call.Fun, go1_26, "new(expr)") + T = Default(x.typ) + if T != x.typ { + // untyped constant: check for overflow. + check.assignment(x, T, "argument to new") + } + check.validVarType(arg, T) } x.mode = value diff --git a/src/go/types/version.go b/src/go/types/version.go index 2a2d341205..8133110398 100644 --- a/src/go/types/version.go +++ b/src/go/types/version.go @@ -43,6 +43,7 @@ var ( go1_21 = asGoVersion("go1.21") go1_22 = asGoVersion("go1.22") go1_23 = asGoVersion("go1.23") + go1_26 = asGoVersion("go1.26") // current (deployed) Go version go_current = asGoVersion(fmt.Sprintf("go1.%d", goversion.Version)) diff --git a/src/internal/types/testdata/check/builtins0.go b/src/internal/types/testdata/check/builtins0.go index ea30fbcbe7..e326b92ac7 100644 --- a/src/internal/types/testdata/check/builtins0.go +++ b/src/internal/types/testdata/check/builtins0.go @@ -609,24 +609,48 @@ func min2() { ) } -func new1() { - _ = new() // ERROR "not enough arguments" +func newInvalid() { + f2 := func() (x, y int) { return } + + _ = new() // ERROR "not enough arguments" _ = new(1, 2) // ERROR "too many arguments" - _ = new("foo" /* ERROR "not a type" */) - p := new(float64) + new /* ERROR "not used" */ (int) + _ = &new /* ERROR "cannot take address" */ (int) + _ = new(int... /* ERROR "invalid use of ..." */) + _ = new(f0 /* ERROR "f0() (no value) used as value or type" */ ()) + _ = new(len /* ERROR "len (built-in) must be called" */) + _ = new(1 /* ERROR "argument to new (overflows)" */ << 70) + _ = new(f2 /* ERRORx "multiple-value.*in single-value context" */ ()) +} + +// new(T) +func newType() { _ = new(struct{ x, y int }) + + p := new(float64) q := new(*float64) _ = *p == **q - new /* ERROR "not used" */ (int) - _ = &new /* ERROR "cannot take address" */ (int) - - _ = new(int... /* ERROR "invalid use of ..." */ ) } -func new2() { +// new(expr), added in go1.26 +func newExpr() { f1 := func() (x []int) { return } - _ = new(f0 /* ERROR "not a type" */ ()) - _ = new(f1 /* ERROR "not a type" */ ()) + var ( + _ *[]int = new(f1()) + _ *func() []int = new(f1) + _ *bool = new(false) + _ *int = new(123) + _ *float64 = new(1.0) + _ *uint = new(uint(3)) + _ *rune = new('a') + _ *string = new("A") + _ *struct{} = new(struct{}{}) + _ *any = new(any) + + // from issue 43125 + _ = new(-1) + _ = new(1 + 1) + ) } func panic1() { diff --git a/src/internal/types/testdata/check/go1_25.go b/src/internal/types/testdata/check/go1_25.go new file mode 100644 index 0000000000..b2ace83343 --- /dev/null +++ b/src/internal/types/testdata/check/go1_25.go @@ -0,0 +1,13 @@ +// -lang=go1.25 + +// Copyright 2025 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. + +// Check Go language version-specific errors. + +//go:build go1.25 + +package p + +var _ = new /* ERROR "new(expr) requires go1.26 or later" */ (123) diff --git a/src/internal/types/testdata/fixedbugs/issue43125.go b/src/internal/types/testdata/fixedbugs/issue43125.go deleted file mode 100644 index d0d6feb2a8..0000000000 --- a/src/internal/types/testdata/fixedbugs/issue43125.go +++ /dev/null @@ -1,8 +0,0 @@ -// 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 p - -var _ = new(- /* ERROR "not a type" */ 1) -var _ = new(1 /* ERROR "not a type" */ + 1) |
