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
import (
"go/types"
"runtime"
"testing"
)
......@@ -144,14 +143,14 @@ var importablePackages = [...]string{
}
func TestInstallationImporter(t *testing.T) {
// This test relies on gccgo being around, which it most likely will be if we
// were compiled with gccgo.
if runtime.Compiler != "gccgo" {
// This test relies on gccgo being around.
gpath := gccgoPath()
if gpath == "" {
t.Skip("This test needs gccgo")
}
var inst GccgoInstallation
err := inst.InitFromDriver("gccgo")
err := inst.InitFromDriver(gpath)
if err != nil {
t.Fatal(err)
}
......@@ -176,12 +175,12 @@ func TestInstallationImporter(t *testing.T) {
// Test for certain specific entities in the imported data.
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: "math", name: "Pi", want: "const Pi untyped float"},
{pkgpath: "math", name: "Sin", want: "func Sin(x float64) float64"},
{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)
}
......
......@@ -62,6 +62,7 @@ func findExportFile(searchpaths []string, pkgpath string) (string, error) {
const (
gccgov1Magic = "v1;\n"
gccgov2Magic = "v2;\n"
gccgov3Magic = "v3;\n"
goimporterMagic = "\n$$ "
archiveMagic = "!<ar"
)
......@@ -90,7 +91,7 @@ func openExportFile(fpath string) (reader io.ReadSeeker, closer io.Closer, err e
var elfreader io.ReaderAt
switch string(magic[:]) {
case gccgov1Magic, gccgov2Magic, goimporterMagic:
case gccgov1Magic, gccgov2Magic, gccgov3Magic, goimporterMagic:
// Raw export data.
reader = f
return
......@@ -195,7 +196,7 @@ func GetImporter(searchpaths []string, initmap map[*types.Package]InitData) Impo
}
switch magics {
case gccgov1Magic, gccgov2Magic:
case gccgov1Magic, gccgov2Magic, gccgov3Magic:
var p parser
p.init(fpath, reader, imports)
pkg = p.parsePackage()
......
......@@ -11,7 +11,6 @@ import (
"os"
"os/exec"
"path/filepath"
"runtime"
"testing"
)
......@@ -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
for _, pkginit := range initdata.Inits {
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
break
}
......@@ -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])
}
// Each init function in the list other than the first one is a
// dependency of the function immediately before it. Check that
// the init functions appear in descending priority order.
priority := initdata.Priority
for _, wantdepinit := range test.wantinits[1:] {
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)
}
}
// FIXME: the original version of this test was written against
// the v1 export data scheme for capturing init functions, so it
// verified the priority values. We moved away from the priority
// scheme some time ago; it is not clear how much work it would be
// to validate the new init export data.
}
}
......@@ -100,7 +80,7 @@ var importerTests = [...]importerTest{
{pkgpath: "time", name: "Nanosecond", want: "const Nanosecond Duration", wantval: "1"},
{pkgpath: "unicode", name: "IsUpper", want: "func IsUpper(r rune) bool"},
{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: "aliases", name: "A14", want: "type A14 = func(int, T0) chan T2"},
{pkgpath: "aliases", name: "C0", want: "type C0 struct{f1 C1; f2 C1}"},
......@@ -109,8 +89,7 @@ var importerTests = [...]importerTest{
}
func TestGoxImporter(t *testing.T) {
testenv.MustHaveGoBuild(t)
testenv.MustHaveExec(t) // this is to skip nacl, js
initmap := make(map[*types.Package]InitData)
imp := GetImporter([]string{"testdata"}, initmap)
......@@ -119,12 +98,24 @@ func TestGoxImporter(t *testing.T) {
}
}
func TestObjImporter(t *testing.T) {
testenv.MustHaveGoBuild(t)
// gccgoPath returns a path to gccgo if it is present (either in
// 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
// were compiled with gccgo.
if runtime.Compiler != "gccgo" {
func TestObjImporter(t *testing.T) {
// This test relies on gccgo being around.
gpath := gccgoPath()
if gpath == "" {
t.Skip("This test needs gccgo")
}
......@@ -144,10 +135,13 @@ func TestObjImporter(t *testing.T) {
for _, test := range importerTests {
gofile := filepath.Join("testdata", test.pkgpath+".go")
if _, err := os.Stat(gofile); os.IsNotExist(err) {
continue
}
ofile := filepath.Join(tmpdir, test.pkgpath+".o")
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()
if err != nil {
t.Logf("%s", out)
......
This diff is collapsed.
......@@ -19,7 +19,7 @@ var typeParserTests = []struct {
{id: "foo", typ: "<type 1 *<type -19>>", want: "*error"},
{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.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 []<type -1>>", want: "[]int8"},
{id: "foo", typ: "<type 1 [42]<type -1>>", want: "[42]int8"},
......@@ -36,6 +36,7 @@ func TestTypeParser(t *testing.T) {
for _, test := range typeParserTests {
var p parser
p.init("test.gox", strings.NewReader(test.typ), make(map[string]*types.Package))
p.version = "v2"
p.pkgname = test.id
p.pkgpath = test.id
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