From 2c51ea11b0f96ece871f84f83fb393ff80ec8f4a Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Wed, 16 Aug 2023 22:37:42 -0700 Subject: [PATCH] cmd/compile/internal/typecheck: push ONEW into go/defer wrappers Currently, we rewrite: go f(new(T)) into: tmp := new(T) go func() { f(tmp) }() However, we can both shrink the closure and improve escape analysis by instead rewriting it into: go func() { f(new(T)) }() This CL does that. Change-Id: Iae16a476368da35123052ca9ff41c49159980458 Reviewed-on: https://go-review.googlesource.com/c/go/+/520340 TryBot-Result: Gopher Robot Reviewed-by: Cuong Manh Le Run-TryBot: Matthew Dempsky Auto-Submit: Matthew Dempsky Reviewed-by: Dmitri Shuralyov --- src/cmd/compile/internal/typecheck/stmt.go | 2 +- test/fixedbugs/issue31573.go | 24 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/cmd/compile/internal/typecheck/stmt.go b/src/cmd/compile/internal/typecheck/stmt.go index 4c21f045af..93a147c335 100644 --- a/src/cmd/compile/internal/typecheck/stmt.go +++ b/src/cmd/compile/internal/typecheck/stmt.go @@ -241,7 +241,7 @@ func tcGoDefer(n *ir.GoDeferStmt) { // the wrapper, so we don't need to allocate space for them within // the closure. switch arg.Op() { - case ir.OLITERAL, ir.ONIL, ir.OMETHEXPR: + case ir.OLITERAL, ir.ONIL, ir.OMETHEXPR, ir.ONEW: return case ir.ONAME: arg := arg.(*ir.Name) diff --git a/test/fixedbugs/issue31573.go b/test/fixedbugs/issue31573.go index a0cff3099a..5197163f04 100644 --- a/test/fixedbugs/issue31573.go +++ b/test/fixedbugs/issue31573.go @@ -19,31 +19,31 @@ func g() { defer f([]*int{new(int), new(int)}...) // ERROR "\[\]\*int{...} does not escape$" "new\(int\) does not escape$" go f() - go f(new(int)) // ERROR "... argument does not escape$" "new\(int\) escapes to heap$" - go f(new(int), new(int)) // ERROR "... argument does not escape$" "new\(int\) escapes to heap$" + go f(new(int)) // ERROR "... argument does not escape$" "new\(int\) does not escape$" + go f(new(int), new(int)) // ERROR "... argument does not escape$" "new\(int\) does not escape$" go f(nil...) go f([]*int{}...) // ERROR "\[\]\*int{} does not escape$" - go f([]*int{new(int)}...) // ERROR "\[\]\*int{...} does not escape$" "new\(int\) escapes to heap$" - go f([]*int{new(int), new(int)}...) // ERROR "\[\]\*int{...} does not escape$" "new\(int\) escapes to heap$" + go f([]*int{new(int)}...) // ERROR "\[\]\*int{...} does not escape$" "new\(int\) does not escape$" + go f([]*int{new(int), new(int)}...) // ERROR "\[\]\*int{...} does not escape$" "new\(int\) does not escape$" for { defer f() - defer f(new(int)) // ERROR "... argument does not escape$" "new\(int\) escapes to heap$" - defer f(new(int), new(int)) // ERROR "... argument does not escape$" "new\(int\) escapes to heap$" + defer f(new(int)) // ERROR "... argument does not escape$" "new\(int\) does not escape$" + defer f(new(int), new(int)) // ERROR "... argument does not escape$" "new\(int\) does not escape$" defer f(nil...) defer f([]*int{}...) // ERROR "\[\]\*int{} does not escape$" - defer f([]*int{new(int)}...) // ERROR "\[\]\*int{...} does not escape$" "new\(int\) escapes to heap$" - defer f([]*int{new(int), new(int)}...) // ERROR "\[\]\*int{...} does not escape$" "new\(int\) escapes to heap$" + defer f([]*int{new(int)}...) // ERROR "\[\]\*int{...} does not escape$" "new\(int\) does not escape$" + defer f([]*int{new(int), new(int)}...) // ERROR "\[\]\*int{...} does not escape$" "new\(int\) does not escape$" go f() - go f(new(int)) // ERROR "... argument does not escape$" "new\(int\) escapes to heap$" - go f(new(int), new(int)) // ERROR "... argument does not escape$" "new\(int\) escapes to heap$" + go f(new(int)) // ERROR "... argument does not escape$" "new\(int\) does not escape$" + go f(new(int), new(int)) // ERROR "... argument does not escape$" "new\(int\) does not escape$" go f(nil...) go f([]*int{}...) // ERROR "\[\]\*int{} does not escape$" - go f([]*int{new(int)}...) // ERROR "\[\]\*int{...} does not escape$" "new\(int\) escapes to heap$" - go f([]*int{new(int), new(int)}...) // ERROR "\[\]\*int{...} does not escape$" "new\(int\) escapes to heap$" + go f([]*int{new(int)}...) // ERROR "\[\]\*int{...} does not escape$" "new\(int\) does not escape$" + go f([]*int{new(int), new(int)}...) // ERROR "\[\]\*int{...} does not escape$" "new\(int\) does not escape$" } } -- 2.44.0