go/analysis/passes/asmdecl: permit return jump without writing to results
RET f(SB) is a tail call. It is okay to not write the results,
as it has not returned to the caller at this point.
Change-Id: I670486d02285c3a346cbc93e91be3b9e61ab77bd
Reviewed-on: https://go-review.googlesource.com/c/tools/+/264319
Trust: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Austin Clements <austin@google.com>
diff --git a/go/analysis/passes/asmdecl/asmdecl.go b/go/analysis/passes/asmdecl/asmdecl.go
index d63855b..eb0016b 100644
--- a/go/analysis/passes/asmdecl/asmdecl.go
+++ b/go/analysis/passes/asmdecl/asmdecl.go
@@ -308,7 +308,8 @@
continue
}
- if strings.Contains(line, "RET") {
+ if strings.Contains(line, "RET") && !strings.Contains(line, "(SB)") {
+ // RET f(SB) is a tail call. It is okay to not write the results.
retLine = append(retLine, lineno)
}
diff --git a/go/analysis/passes/asmdecl/testdata/src/a/asm.go b/go/analysis/passes/asmdecl/testdata/src/a/asm.go
index 27470c5..6bcfb2f 100644
--- a/go/analysis/passes/asmdecl/testdata/src/a/asm.go
+++ b/go/analysis/passes/asmdecl/testdata/src/a/asm.go
@@ -51,3 +51,5 @@
func pickStableABI(x int)
func pickInternalABI(x int)
func pickFutureABI(x int)
+
+func retjmp() int
diff --git a/go/analysis/passes/asmdecl/testdata/src/a/asm1.s b/go/analysis/passes/asmdecl/testdata/src/a/asm1.s
index 8fa0401..8c43223 100644
--- a/go/analysis/passes/asmdecl/testdata/src/a/asm1.s
+++ b/go/analysis/passes/asmdecl/testdata/src/a/asm1.s
@@ -345,3 +345,7 @@
TEXT ·pickFutureABI<ABISomethingNotyetInvented>(SB), NOSPLIT, $32
MOVQ x+0(FP), AX
RET
+
+// return jump
+TEXT ·retjmp(SB), NOSPLIT, $0-8
+ RET retjmp1(SB) // It's okay to not write results if there's a tail call.