go/ssa: convert the objlookup tests to the new marker syntax
Change-Id: I5df3a3cc3d3ab236a6ad964914393a2ccb29803b
Reviewed-on: https://go-review.googlesource.com/c/145637
Run-TryBot: Ian Cottrell <iancottrell@google.com>
Run-TryBot: Michael Matloob <matloob@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
diff --git a/go/ssa/source_test.go b/go/ssa/source_test.go
index e3e7023..9dc3c66 100644
--- a/go/ssa/source_test.go
+++ b/go/ssa/source_test.go
@@ -13,8 +13,8 @@
"go/parser"
"go/token"
"go/types"
+ "io/ioutil"
"os"
- "regexp"
"runtime"
"strings"
"testing"
@@ -32,10 +32,14 @@
}
conf := loader.Config{ParserMode: parser.ParseComments}
- f, err := conf.ParseFile("testdata/objlookup.go", nil)
+ src, err := ioutil.ReadFile("testdata/objlookup.go")
if err != nil {
- t.Error(err)
- return
+ t.Fatal(err)
+ }
+ readFile := func(filename string) ([]byte, error) { return src, nil }
+ f, err := conf.ParseFile("testdata/objlookup.go", src)
+ if err != nil {
+ t.Fatal(err)
}
conf.CreateFromFiles("main", f)
@@ -43,16 +47,40 @@
// kind of ssa.Value we expect (represented "Constant", "&Alloc").
expectations := make(map[string]string)
- // Find all annotations of form x::BinOp, &y::Alloc, etc.
- re := regexp.MustCompile(`(\b|&)?(\w*)::(\w*)\b`)
- for _, c := range f.Comments {
- text := c.Text()
- pos := conf.Fset.Position(c.Pos())
- for _, m := range re.FindAllStringSubmatch(text, -1) {
- key := fmt.Sprintf("%s:%d", m[2], pos.Line)
- value := m[1] + m[3]
- expectations[key] = value
+ // Each note of the form @ssa(x, "BinOp") in testdata/objlookup.go
+ // specifies an expectation that an object named x declared on the
+ // same line is associated with an an ssa.Value of type *ssa.BinOp.
+ notes, err := expect.Extract(conf.Fset, f)
+ if err != nil {
+ t.Fatal(err)
+ }
+ for _, n := range notes {
+ if n.Name != "ssa" {
+ t.Errorf("%v: unexpected note type %q, want \"ssa\"", conf.Fset.Position(n.Pos), n.Name)
+ continue
}
+ if len(n.Args) != 2 {
+ t.Errorf("%v: ssa has %d args, want 2", conf.Fset.Position(n.Pos), len(n.Args))
+ continue
+ }
+ ident, ok := n.Args[0].(expect.Identifier)
+ if !ok {
+ t.Errorf("%v: got %v for arg 1, want identifier", conf.Fset.Position(n.Pos), n.Args[0])
+ continue
+ }
+ exp, ok := n.Args[1].(string)
+ if !ok {
+ t.Errorf("%v: got %v for arg 2, want string", conf.Fset.Position(n.Pos), n.Args[1])
+ continue
+ }
+ p, _, err := expect.MatchBefore(conf.Fset, readFile, n.Pos, string(ident))
+ if err != nil {
+ t.Error(err)
+ continue
+ }
+ pos := conf.Fset.Position(p)
+ key := fmt.Sprintf("%s:%d", ident, pos.Line)
+ expectations[key] = exp
}
iprog, err := conf.Load()
diff --git a/go/ssa/testdata/objlookup.go b/go/ssa/testdata/objlookup.go
index 1aaa417..d110add 100644
--- a/go/ssa/testdata/objlookup.go
+++ b/go/ssa/testdata/objlookup.go
@@ -24,7 +24,7 @@
const globalConst = 0
-var globalVar int // &globalVar::Global
+var globalVar int //@ ssa(globalVar,"&Global")
func globalFunc() {}
@@ -33,128 +33,128 @@
}
type S struct {
- x int // x::nil
+ x int //@ ssa(x,"nil")
}
func main() {
- print(globalVar) // globalVar::UnOp
- globalVar = 1 // globalVar::Const
+ print(globalVar) //@ ssa(globalVar,"UnOp")
+ globalVar = 1 //@ ssa(globalVar,"Const")
- var v0 int = 1 // v0::Const (simple local value spec)
- if v0 > 0 { // v0::Const
- v0 = 2 // v0::Const
+ var v0 int = 1 //@ ssa(v0,"Const") // simple local value spec
+ if v0 > 0 { //@ ssa(v0,"Const")
+ v0 = 2 //@ ssa(v0,"Const")
}
- print(v0) // v0::Phi
+ print(v0) //@ ssa(v0,"Phi")
// v1 is captured and thus implicitly address-taken.
- var v1 int = 1 // v1::Const
- v1 = 2 // v1::Const
- fmt.Println(v1) // v1::UnOp (load)
- f := func(param int) { // f::MakeClosure param::Parameter
- if y := 1; y > 0 { // y::Const
- print(v1, param) // v1::UnOp (load) param::Parameter
+ var v1 int = 1 //@ ssa(v1,"Const")
+ v1 = 2 //@ ssa(v1,"Const")
+ fmt.Println(v1) //@ ssa(v1,"UnOp") // load
+ f := func(param int) { //@ ssa(f,"MakeClosure"), ssa(param,"Parameter")
+ if y := 1; y > 0 { //@ ssa(y,"Const")
+ print(v1, param) //@ ssa(v1,"UnOp") /*load*/, ssa(param,"Parameter")
}
- param = 2 // param::Const
- println(param) // param::Const
+ param = 2 //@ ssa(param,"Const")
+ println(param) //@ ssa(param,"Const")
}
- f(0) // f::MakeClosure
+ f(0) //@ ssa(f,"MakeClosure")
- var v2 int // v2::Const (implicitly zero-initialized local value spec)
- print(v2) // v2::Const
+ var v2 int //@ ssa(v2,"Const") // implicitly zero-initialized local value spec
+ print(v2) //@ ssa(v2,"Const")
- m := make(map[string]int) // m::MakeMap
+ m := make(map[string]int) //@ ssa(m,"MakeMap")
// Local value spec with multi-valued RHS:
- var v3, v4 = m[""] // v3::Extract v4::Extract m::MakeMap
- print(v3) // v3::Extract
- print(v4) // v4::Extract
+ var v3, v4 = m[""] //@ ssa(v3,"Extract"), ssa(v4,"Extract"), ssa(m,"MakeMap")
+ print(v3) //@ ssa(v3,"Extract")
+ print(v4) //@ ssa(v4,"Extract")
- v3++ // v3::BinOp (assign with op)
- v3 += 2 // v3::BinOp (assign with op)
+ v3++ //@ ssa(v3,"BinOp") // assign with op
+ v3 += 2 //@ ssa(v3,"BinOp") // assign with op
- v5, v6 := false, "" // v5::Const v6::Const (defining assignment)
- print(v5) // v5::Const
- print(v6) // v6::Const
+ v5, v6 := false, "" //@ ssa(v5,"Const"), ssa(v6,"Const") // defining assignment
+ print(v5) //@ ssa(v5,"Const")
+ print(v6) //@ ssa(v6,"Const")
- var v7 S // &v7::Alloc
- v7.x = 1 // &v7::Alloc &x::FieldAddr
- print(v7.x) // &v7::Alloc &x::FieldAddr
+ var v7 S //@ ssa(v7,"&Alloc")
+ v7.x = 1 //@ ssa(v7,"&Alloc"), ssa(x,"&FieldAddr")
+ print(v7.x) //@ ssa(v7,"&Alloc"), ssa(x,"&FieldAddr")
- var v8 [1]int // &v8::Alloc
- v8[0] = 0 // &v8::Alloc
- print(v8[:]) // &v8::Alloc
- _ = v8[0] // &v8::Alloc
- _ = v8[:][0] // &v8::Alloc
- v8ptr := &v8 // v8ptr::Alloc &v8::Alloc
- _ = v8ptr[0] // v8ptr::Alloc
- _ = *v8ptr // v8ptr::Alloc
+ var v8 [1]int //@ ssa(v8,"&Alloc")
+ v8[0] = 0 //@ ssa(v8,"&Alloc")
+ print(v8[:]) //@ ssa(v8,"&Alloc")
+ _ = v8[0] //@ ssa(v8,"&Alloc")
+ _ = v8[:][0] //@ ssa(v8,"&Alloc")
+ v8ptr := &v8 //@ ssa(v8ptr,"Alloc"), ssa(v8,"&Alloc")
+ _ = v8ptr[0] //@ ssa(v8ptr,"Alloc")
+ _ = *v8ptr //@ ssa(v8ptr,"Alloc")
- v8a := make([]int, 1) // v8a::Slice
- v8a[0] = 0 // v8a::Slice
- print(v8a[:]) // v8a::Slice
+ v8a := make([]int, 1) //@ ssa(v8a,"Slice")
+ v8a[0] = 0 //@ ssa(v8a,"Slice")
+ print(v8a[:]) //@ ssa(v8a,"Slice")
- v9 := S{} // &v9::Alloc
+ v9 := S{} //@ ssa(v9,"&Alloc")
- v10 := &v9 // v10::Alloc &v9::Alloc
- _ = v10 // v10::Alloc
+ v10 := &v9 //@ ssa(v10,"Alloc"), ssa(v9,"&Alloc")
+ _ = v10 //@ ssa(v10,"Alloc")
- var v11 *J = nil // v11::Const
- v11.method() // v11::Const
+ var v11 *J = nil //@ ssa(v11,"Const")
+ v11.method() //@ ssa(v11,"Const")
- var v12 J // &v12::Alloc
- v12.method() // &v12::Alloc (implicitly address-taken)
+ var v12 J //@ ssa(v12,"&Alloc")
+ v12.method() //@ ssa(v12,"&Alloc") // implicitly address-taken
// NB, in the following, 'method' resolves to the *types.Func
// of (*J).method, so it doesn't help us locate the specific
// ssa.Values here: a bound-method closure and a promotion
// wrapper.
- _ = v11.method // v11::Const
- _ = (*struct{ J }).method // J::nil
+ _ = v11.method //@ ssa(v11,"Const")
+ _ = (*struct{ J }).method //@ ssa(J,"nil")
// These vars are not optimised away.
if false {
- v13 := 0 // v13::Const
- println(v13) // v13::Const
+ v13 := 0 //@ ssa(v13,"Const")
+ println(v13) //@ ssa(v13,"Const")
}
- switch x := 1; x { // x::Const
- case v0: // v0::Phi
+ switch x := 1; x { //@ ssa(x,"Const")
+ case v0: //@ ssa(v0,"Phi")
}
- for k, v := range m { // k::Extract v::Extract m::MakeMap
- _ = k // k::Extract
- v++ // v::BinOp
+ for k, v := range m { //@ ssa(k,"Extract"), ssa(v,"Extract"), ssa(m,"MakeMap")
+ _ = k //@ ssa(k,"Extract")
+ v++ //@ ssa(v,"BinOp")
}
- if y := 0; y > 1 { // y::Const y::Const
+ if y := 0; y > 1 { //@ ssa(y,"Const"), ssa(y,"Const")
}
- var i interface{} // i::Const (nil interface)
- i = 1 // i::MakeInterface
- switch i := i.(type) { // i::MakeInterface i::MakeInterface
+ var i interface{} //@ ssa(i,"Const") // nil interface
+ i = 1 //@ ssa(i,"MakeInterface")
+ switch i := i.(type) { //@ ssa(i,"MakeInterface"), ssa(i,"MakeInterface")
case int:
- println(i) // i::Extract
+ println(i) //@ ssa(i,"Extract")
}
- ch := make(chan int) // ch::MakeChan
+ ch := make(chan int) //@ ssa(ch,"MakeChan")
select {
- case x := <-ch: // x::UnOp (receive) ch::MakeChan
- _ = x // x::UnOp
+ case x := <-ch: //@ ssa(x,"UnOp") /*receive*/, ssa(ch,"MakeChan")
+ _ = x //@ ssa(x,"UnOp")
}
// .Op is an inter-package FieldVal-selection.
- var err os.PathError // &err::Alloc
- _ = err.Op // &err::Alloc &Op::FieldAddr
- _ = &err.Op // &err::Alloc &Op::FieldAddr
+ var err os.PathError //@ ssa(err,"&Alloc")
+ _ = err.Op //@ ssa(err,"&Alloc"), ssa(Op,"&FieldAddr")
+ _ = &err.Op //@ ssa(err,"&Alloc"), ssa(Op,"&FieldAddr")
// Exercise corner-cases of lvalues vs rvalues.
// (Guessing IsAddr from the 'pointerness' won't cut it here.)
type N *N
- var n N // n::Const
- n1 := n // n1::Const n::Const
- n2 := &n1 // n2::Alloc &n1::Alloc
- n3 := *n2 // n3::UnOp n2::Alloc
- n4 := **n3 // n4::UnOp n3::UnOp
- _ = n4 // n4::UnOp
+ var n N //@ ssa(n,"Const")
+ n1 := n //@ ssa(n1,"Const"), ssa(n,"Const")
+ n2 := &n1 //@ ssa(n2,"Alloc"), ssa(n1,"&Alloc")
+ n3 := *n2 //@ ssa(n3,"UnOp"), ssa(n2,"Alloc")
+ n4 := **n3 //@ ssa(n4,"UnOp"), ssa(n3,"UnOp")
+ _ = n4 //@ ssa(n4,"UnOp")
}