go/analysis/passes/sigchanyzer: copy to avoid modifying the AST

The sigchanyzer pass suggests fixes, but it does that
by altering the channel declaration argument.
That causes the buildssa.Analyzer fail to fail,
along with crashing other passes that depend on it.

To fix this, we make a copy of the channel's declaration arguments,
and modify the copy instead.

Fixes golang/go#46129

Change-Id: I807d36abd49cd3ccc2cc9f907aa98349b2e3231f
Reviewed-on: https://go-review.googlesource.com/c/tools/+/319211
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
diff --git a/go/analysis/passes/sigchanyzer/sigchanyzer.go b/go/analysis/passes/sigchanyzer/sigchanyzer.go
index b00aa7e..0d6c8eb 100644
--- a/go/analysis/passes/sigchanyzer/sigchanyzer.go
+++ b/go/analysis/passes/sigchanyzer/sigchanyzer.go
@@ -59,12 +59,19 @@
 		if chanDecl == nil || len(chanDecl.Args) != 1 {
 			return
 		}
-		chanDecl.Args = append(chanDecl.Args, &ast.BasicLit{
+
+		// Make a copy of the channel's declaration to avoid
+		// mutating the AST. See https://golang.org/issue/46129.
+		chanDeclCopy := &ast.CallExpr{}
+		*chanDeclCopy = *chanDecl
+		chanDeclCopy.Args = append([]ast.Expr(nil), chanDecl.Args...)
+		chanDeclCopy.Args = append(chanDeclCopy.Args, &ast.BasicLit{
 			Kind:  token.INT,
 			Value: "1",
 		})
+
 		var buf bytes.Buffer
-		if err := format.Node(&buf, token.NewFileSet(), chanDecl); err != nil {
+		if err := format.Node(&buf, token.NewFileSet(), chanDeclCopy); err != nil {
 			return
 		}
 		pass.Report(analysis.Diagnostic{