]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile/internal/typecheck: push ONEW into go/defer wrappers
authorMatthew Dempsky <mdempsky@google.com>
Thu, 17 Aug 2023 05:37:42 +0000 (22:37 -0700)
committerGopher Robot <gobot@golang.org>
Thu, 17 Aug 2023 19:37:04 +0000 (19:37 +0000)
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 <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
src/cmd/compile/internal/typecheck/stmt.go
test/fixedbugs/issue31573.go

index 4c21f045afaea45fca681b2bfac3b530e13ef682..93a147c335c696b5b7fe2096d3fca0a1748fce58 100644 (file)
@@ -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)
index a0cff3099aef3fdd74cb6d6dc5302d98f4157d7a..5197163f04f0a99ea5227740d778147da3315373 100644 (file)
@@ -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$"
        }
 }