go/ssa: support unsafe.Add and unsafe.Slice
Fixes golang/go#47091
Change-Id: Id59375a3083520275025f58879c8950b0560e25a
Reviewed-on: https://go-review.googlesource.com/c/tools/+/333110
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
diff --git a/go/ssa/builder.go b/go/ssa/builder.go
index a13a884..2d0fdaa 100644
--- a/go/ssa/builder.go
+++ b/go/ssa/builder.go
@@ -693,6 +693,10 @@
case *ast.SelectorExpr:
sel, ok := fn.Pkg.info.Selections[e]
if !ok {
+ // builtin unsafe.{Add,Slice}
+ if obj, ok := fn.Pkg.info.Uses[e.Sel].(*types.Builtin); ok {
+ return &Builtin{name: obj.Name(), sig: tv.Type.(*types.Signature)}
+ }
// qualified identifier
return b.expr(fn, e.Sel)
}
diff --git a/go/ssa/builder_go117_test.go b/go/ssa/builder_go117_test.go
index 93316c1..e7ba214 100644
--- a/go/ssa/builder_go117_test.go
+++ b/go/ssa/builder_go117_test.go
@@ -9,6 +9,7 @@
import (
"go/ast"
+ "go/importer"
"go/parser"
"go/token"
"go/types"
@@ -18,24 +19,33 @@
"golang.org/x/tools/go/ssa/ssautil"
)
-func TestSliceToArrayPtr(t *testing.T) {
- src := `package p
-
-func f() {
- var s []byte
- _ = (*[4]byte)(s)
-}
-`
- fset := token.NewFileSet()
- f, err := parser.ParseFile(fset, "p.go", src, parser.ParseComments)
- if err != nil {
- t.Fatal(err)
+func TestBuildPackageGo117(t *testing.T) {
+ tests := []struct {
+ name string
+ src string
+ importer types.Importer
+ }{
+ {"slice to array pointer", "package p; var s []byte; var _ = (*[4]byte)(s)", nil},
+ {"unsafe slice", `package p; import "unsafe"; var _ = unsafe.Add(nil, 0)`, importer.Default()},
+ {"unsafe add", `package p; import "unsafe"; var _ = unsafe.Slice((*int)(nil), 0)`, importer.Default()},
}
- files := []*ast.File{f}
- pkg := types.NewPackage("p", "")
- conf := &types.Config{}
- if _, _, err := ssautil.BuildPackage(conf, fset, pkg, files, ssa.SanityCheckFunctions); err != nil {
- t.Fatalf("unexpected error: %v", err)
+ for _, tc := range tests {
+ tc := tc
+ t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
+ fset := token.NewFileSet()
+ f, err := parser.ParseFile(fset, "p.go", tc.src, parser.ParseComments)
+ if err != nil {
+ t.Error(err)
+ }
+ files := []*ast.File{f}
+
+ pkg := types.NewPackage("p", "")
+ conf := &types.Config{Importer: tc.importer}
+ if _, _, err := ssautil.BuildPackage(conf, fset, pkg, files, ssa.SanityCheckFunctions); err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+ })
}
}