aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder
diff options
context:
space:
mode:
authorAlan Donovan <adonovan@google.com>2025-09-18 14:04:43 -0400
committerGopher Robot <gobot@golang.org>2025-09-23 13:12:12 -0700
commit7bc1935db55c9d182617aba074f048f9c7573680 (patch)
tree042fbd7352c4a890a43f19d214b00d4bbc26b19f /src/cmd/compile/internal/noder
parenteb78f13c9f195ba11fd9518257b6e45997b14de5 (diff)
downloadgo-7bc1935db55c9d182617aba074f048f9c7573680.tar.xz
cmd/compile/internal: support new(expr)
This CL adds compiler support for new(expr), a feature of go1.26 that allows the user to specify the initial value of the variable instead of its type. Also, a basic test of dynamic behavior. See CL 704737 for spec change and CL 704935 for type-checker changes. For #45624 Change-Id: I65d27de1ee3aabb819b57cce8ea77f3073447757 Reviewed-on: https://go-review.googlesource.com/c/go/+/705157 Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Mateusz Poliwczak <mpoliwczak34@gmail.com> Auto-Submit: Alan Donovan <adonovan@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com>
Diffstat (limited to 'src/cmd/compile/internal/noder')
-rw-r--r--src/cmd/compile/internal/noder/reader.go13
-rw-r--r--src/cmd/compile/internal/noder/writer.go8
2 files changed, 18 insertions, 3 deletions
diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go
index 45e2bfd727..ca7c6bf151 100644
--- a/src/cmd/compile/internal/noder/reader.go
+++ b/src/cmd/compile/internal/noder/reader.go
@@ -2431,8 +2431,16 @@ func (r *reader) expr() (res ir.Node) {
case exprNew:
pos := r.pos()
- typ := r.exprType()
- return typecheck.Expr(ir.NewUnaryExpr(pos, ir.ONEW, typ))
+ if r.Bool() {
+ // new(expr) -> tmp := expr; &tmp
+ x := r.expr()
+ var init ir.Nodes
+ addr := ir.NewAddrExpr(pos, r.tempCopy(pos, x, &init))
+ addr.SetInit(init)
+ return typecheck.Expr(addr)
+ }
+ // new(T)
+ return typecheck.Expr(ir.NewUnaryExpr(pos, ir.ONEW, r.exprType()))
case exprSizeof:
return ir.NewUintptr(r.pos(), r.typ().Size())
@@ -3239,6 +3247,7 @@ func (r *reader) exprType() ir.Node {
var rtype, itab ir.Node
if r.Bool() {
+ // non-empty interface
typ, rtype, _, _, itab = r.itab(pos)
if !typ.IsInterface() {
rtype = nil // TODO(mdempsky): Leave set?
diff --git a/src/cmd/compile/internal/noder/writer.go b/src/cmd/compile/internal/noder/writer.go
index 54e5f1ea5f..9c90d221c2 100644
--- a/src/cmd/compile/internal/noder/writer.go
+++ b/src/cmd/compile/internal/noder/writer.go
@@ -2035,10 +2035,16 @@ func (w *writer) expr(expr syntax.Expr) {
case "new":
assert(len(expr.ArgList) == 1)
assert(!expr.HasDots)
+ arg := expr.ArgList[0]
w.Code(exprNew)
w.pos(expr)
- w.exprType(nil, expr.ArgList[0])
+ tv := w.p.typeAndValue(arg)
+ if w.Bool(!tv.IsType()) {
+ w.expr(arg) // new(expr), go1.26
+ } else {
+ w.exprType(nil, arg) // new(T)
+ }
return
case "Sizeof":