Commit 984be3b0 authored by Than McIntosh's avatar Than McIntosh

go/internal/gccgoimporter: enhance for new export data, fix test issues

This patch merges in support for reading indexed type export data,
from the gofrontend CL https://golang.org/cl/143022 (which includes
a change in the export data version number from V2 to V3).

Also fixes the key tests to insure that they run both in gccgo builds
and main Go repo builds if "gccgo" is present (prior to this the tests
were not running in either scenario); this required fixing up some of
the expected results.

Fixes #28961.

Change-Id: I644d171f2a46be9160f89dada06ab3c20468bab7
Reviewed-on: https://go-review.googlesource.com/c/149957
Run-TryBot: Than McIntosh <thanm@google.com>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent ca374923
...@@ -6,7 +6,6 @@ package gccgoimporter ...@@ -6,7 +6,6 @@ package gccgoimporter
import ( import (
"go/types" "go/types"
"runtime"
"testing" "testing"
) )
...@@ -144,14 +143,14 @@ var importablePackages = [...]string{ ...@@ -144,14 +143,14 @@ var importablePackages = [...]string{
} }
func TestInstallationImporter(t *testing.T) { func TestInstallationImporter(t *testing.T) {
// This test relies on gccgo being around, which it most likely will be if we // This test relies on gccgo being around.
// were compiled with gccgo. gpath := gccgoPath()
if runtime.Compiler != "gccgo" { if gpath == "" {
t.Skip("This test needs gccgo") t.Skip("This test needs gccgo")
} }
var inst GccgoInstallation var inst GccgoInstallation
err := inst.InitFromDriver("gccgo") err := inst.InitFromDriver(gpath)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -176,12 +175,12 @@ func TestInstallationImporter(t *testing.T) { ...@@ -176,12 +175,12 @@ func TestInstallationImporter(t *testing.T) {
// Test for certain specific entities in the imported data. // Test for certain specific entities in the imported data.
for _, test := range [...]importerTest{ for _, test := range [...]importerTest{
{pkgpath: "io", name: "Reader", want: "type Reader interface{Read(p []uint8) (n int, err error)}"}, {pkgpath: "io", name: "Reader", want: "type Reader interface{Read(p []byte) (n int, err error)}"},
{pkgpath: "io", name: "ReadWriter", want: "type ReadWriter interface{Reader; Writer}"}, {pkgpath: "io", name: "ReadWriter", want: "type ReadWriter interface{Reader; Writer}"},
{pkgpath: "math", name: "Pi", want: "const Pi untyped float"}, {pkgpath: "math", name: "Pi", want: "const Pi untyped float"},
{pkgpath: "math", name: "Sin", want: "func Sin(x float64) float64"}, {pkgpath: "math", name: "Sin", want: "func Sin(x float64) float64"},
{pkgpath: "sort", name: "Ints", want: "func Ints(a []int)"}, {pkgpath: "sort", name: "Ints", want: "func Ints(a []int)"},
{pkgpath: "unsafe", name: "Pointer", want: "type Pointer unsafe.Pointer"}, {pkgpath: "unsafe", name: "Pointer", want: "type Pointer"},
} { } {
runImporterTest(t, imp, nil, &test) runImporterTest(t, imp, nil, &test)
} }
......
...@@ -62,6 +62,7 @@ func findExportFile(searchpaths []string, pkgpath string) (string, error) { ...@@ -62,6 +62,7 @@ func findExportFile(searchpaths []string, pkgpath string) (string, error) {
const ( const (
gccgov1Magic = "v1;\n" gccgov1Magic = "v1;\n"
gccgov2Magic = "v2;\n" gccgov2Magic = "v2;\n"
gccgov3Magic = "v3;\n"
goimporterMagic = "\n$$ " goimporterMagic = "\n$$ "
archiveMagic = "!<ar" archiveMagic = "!<ar"
) )
...@@ -90,7 +91,7 @@ func openExportFile(fpath string) (reader io.ReadSeeker, closer io.Closer, err e ...@@ -90,7 +91,7 @@ func openExportFile(fpath string) (reader io.ReadSeeker, closer io.Closer, err e
var elfreader io.ReaderAt var elfreader io.ReaderAt
switch string(magic[:]) { switch string(magic[:]) {
case gccgov1Magic, gccgov2Magic, goimporterMagic: case gccgov1Magic, gccgov2Magic, gccgov3Magic, goimporterMagic:
// Raw export data. // Raw export data.
reader = f reader = f
return return
...@@ -195,7 +196,7 @@ func GetImporter(searchpaths []string, initmap map[*types.Package]InitData) Impo ...@@ -195,7 +196,7 @@ func GetImporter(searchpaths []string, initmap map[*types.Package]InitData) Impo
} }
switch magics { switch magics {
case gccgov1Magic, gccgov2Magic: case gccgov1Magic, gccgov2Magic, gccgov3Magic:
var p parser var p parser
p.init(fpath, reader, imports) p.init(fpath, reader, imports)
pkg = p.parsePackage() pkg = p.parsePackage()
......
...@@ -11,7 +11,6 @@ import ( ...@@ -11,7 +11,6 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"runtime"
"testing" "testing"
) )
...@@ -53,9 +52,6 @@ func runImporterTest(t *testing.T, imp Importer, initmap map[*types.Package]Init ...@@ -53,9 +52,6 @@ func runImporterTest(t *testing.T, imp Importer, initmap map[*types.Package]Init
// Check that the package's own init function has the package's priority // Check that the package's own init function has the package's priority
for _, pkginit := range initdata.Inits { for _, pkginit := range initdata.Inits {
if pkginit.InitFunc == test.wantinits[0] { if pkginit.InitFunc == test.wantinits[0] {
if initdata.Priority != pkginit.Priority {
t.Errorf("%s: got self priority %d; want %d", test.pkgpath, pkginit.Priority, initdata.Priority)
}
found = true found = true
break break
} }
...@@ -65,27 +61,11 @@ func runImporterTest(t *testing.T, imp Importer, initmap map[*types.Package]Init ...@@ -65,27 +61,11 @@ func runImporterTest(t *testing.T, imp Importer, initmap map[*types.Package]Init
t.Errorf("%s: could not find expected function %q", test.pkgpath, test.wantinits[0]) t.Errorf("%s: could not find expected function %q", test.pkgpath, test.wantinits[0])
} }
// Each init function in the list other than the first one is a // FIXME: the original version of this test was written against
// dependency of the function immediately before it. Check that // the v1 export data scheme for capturing init functions, so it
// the init functions appear in descending priority order. // verified the priority values. We moved away from the priority
priority := initdata.Priority // scheme some time ago; it is not clear how much work it would be
for _, wantdepinit := range test.wantinits[1:] { // to validate the new init export data.
found = false
for _, pkginit := range initdata.Inits {
if pkginit.InitFunc == wantdepinit {
if priority <= pkginit.Priority {
t.Errorf("%s: got dep priority %d; want less than %d", test.pkgpath, pkginit.Priority, priority)
}
found = true
priority = pkginit.Priority
break
}
}
if !found {
t.Errorf("%s: could not find expected function %q", test.pkgpath, wantdepinit)
}
}
} }
} }
...@@ -100,7 +80,7 @@ var importerTests = [...]importerTest{ ...@@ -100,7 +80,7 @@ var importerTests = [...]importerTest{
{pkgpath: "time", name: "Nanosecond", want: "const Nanosecond Duration", wantval: "1"}, {pkgpath: "time", name: "Nanosecond", want: "const Nanosecond Duration", wantval: "1"},
{pkgpath: "unicode", name: "IsUpper", want: "func IsUpper(r rune) bool"}, {pkgpath: "unicode", name: "IsUpper", want: "func IsUpper(r rune) bool"},
{pkgpath: "unicode", name: "MaxRune", want: "const MaxRune untyped rune", wantval: "1114111"}, {pkgpath: "unicode", name: "MaxRune", want: "const MaxRune untyped rune", wantval: "1114111"},
{pkgpath: "imports", wantinits: []string{"imports..import", "fmt..import", "math..import"}}, {pkgpath: "imports", wantinits: []string{"imports..import", "fmt..import"}},
{pkgpath: "importsar", name: "Hello", want: "var Hello string"}, {pkgpath: "importsar", name: "Hello", want: "var Hello string"},
{pkgpath: "aliases", name: "A14", want: "type A14 = func(int, T0) chan T2"}, {pkgpath: "aliases", name: "A14", want: "type A14 = func(int, T0) chan T2"},
{pkgpath: "aliases", name: "C0", want: "type C0 struct{f1 C1; f2 C1}"}, {pkgpath: "aliases", name: "C0", want: "type C0 struct{f1 C1; f2 C1}"},
...@@ -109,8 +89,7 @@ var importerTests = [...]importerTest{ ...@@ -109,8 +89,7 @@ var importerTests = [...]importerTest{
} }
func TestGoxImporter(t *testing.T) { func TestGoxImporter(t *testing.T) {
testenv.MustHaveGoBuild(t) testenv.MustHaveExec(t) // this is to skip nacl, js
initmap := make(map[*types.Package]InitData) initmap := make(map[*types.Package]InitData)
imp := GetImporter([]string{"testdata"}, initmap) imp := GetImporter([]string{"testdata"}, initmap)
...@@ -119,12 +98,24 @@ func TestGoxImporter(t *testing.T) { ...@@ -119,12 +98,24 @@ func TestGoxImporter(t *testing.T) {
} }
} }
func TestObjImporter(t *testing.T) { // gccgoPath returns a path to gccgo if it is present (either in
testenv.MustHaveGoBuild(t) // path or specified via GCCGO environment variable), or an
// empty string if no gccgo is available.
func gccgoPath() string {
gccgoname := os.Getenv("GCCGO")
if gccgoname == "" {
gccgoname = "gccgo"
}
if gpath, gerr := exec.LookPath(gccgoname); gerr == nil {
return gpath
}
return ""
}
// This test relies on gccgo being around, which it most likely will be if we func TestObjImporter(t *testing.T) {
// were compiled with gccgo. // This test relies on gccgo being around.
if runtime.Compiler != "gccgo" { gpath := gccgoPath()
if gpath == "" {
t.Skip("This test needs gccgo") t.Skip("This test needs gccgo")
} }
...@@ -144,10 +135,13 @@ func TestObjImporter(t *testing.T) { ...@@ -144,10 +135,13 @@ func TestObjImporter(t *testing.T) {
for _, test := range importerTests { for _, test := range importerTests {
gofile := filepath.Join("testdata", test.pkgpath+".go") gofile := filepath.Join("testdata", test.pkgpath+".go")
if _, err := os.Stat(gofile); os.IsNotExist(err) {
continue
}
ofile := filepath.Join(tmpdir, test.pkgpath+".o") ofile := filepath.Join(tmpdir, test.pkgpath+".o")
afile := filepath.Join(artmpdir, "lib"+test.pkgpath+".a") afile := filepath.Join(artmpdir, "lib"+test.pkgpath+".a")
cmd := exec.Command("gccgo", "-fgo-pkgpath="+test.pkgpath, "-c", "-o", ofile, gofile) cmd := exec.Command(gpath, "-fgo-pkgpath="+test.pkgpath, "-c", "-o", ofile, gofile)
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
t.Logf("%s", out) t.Logf("%s", out)
......
This diff is collapsed.
...@@ -19,7 +19,7 @@ var typeParserTests = []struct { ...@@ -19,7 +19,7 @@ var typeParserTests = []struct {
{id: "foo", typ: "<type 1 *<type -19>>", want: "*error"}, {id: "foo", typ: "<type 1 *<type -19>>", want: "*error"},
{id: "foo", typ: "<type 1 *any>", want: "unsafe.Pointer"}, {id: "foo", typ: "<type 1 *any>", want: "unsafe.Pointer"},
{id: "foo", typ: "<type 1 \"Bar\" <type 2 *<type 1>>>", want: "foo.Bar", underlying: "*foo.Bar"}, {id: "foo", typ: "<type 1 \"Bar\" <type 2 *<type 1>>>", want: "foo.Bar", underlying: "*foo.Bar"},
{id: "foo", typ: "<type 1 \"bar.Foo\" \"bar\" <type -1> func (? <type 1>) M (); >", want: "bar.Foo", underlying: "int8", methods: "func (bar.Foo).M()"}, {id: "foo", typ: "<type 1 \"bar.Foo\" \"bar\" <type -1>\nfunc (? <type 1>) M ();\n>", want: "bar.Foo", underlying: "int8", methods: "func (bar.Foo).M()"},
{id: "foo", typ: "<type 1 \".bar.foo\" \"bar\" <type -1>>", want: "bar.foo", underlying: "int8"}, {id: "foo", typ: "<type 1 \".bar.foo\" \"bar\" <type -1>>", want: "bar.foo", underlying: "int8"},
{id: "foo", typ: "<type 1 []<type -1>>", want: "[]int8"}, {id: "foo", typ: "<type 1 []<type -1>>", want: "[]int8"},
{id: "foo", typ: "<type 1 [42]<type -1>>", want: "[42]int8"}, {id: "foo", typ: "<type 1 [42]<type -1>>", want: "[42]int8"},
...@@ -36,6 +36,7 @@ func TestTypeParser(t *testing.T) { ...@@ -36,6 +36,7 @@ func TestTypeParser(t *testing.T) {
for _, test := range typeParserTests { for _, test := range typeParserTests {
var p parser var p parser
p.init("test.gox", strings.NewReader(test.typ), make(map[string]*types.Package)) p.init("test.gox", strings.NewReader(test.typ), make(map[string]*types.Package))
p.version = "v2"
p.pkgname = test.id p.pkgname = test.id
p.pkgpath = test.id p.pkgpath = test.id
p.maybeCreatePackage() p.maybeCreatePackage()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment