llgoi: Fix type identity for imported binary packages.
authorPeter Collingbourne <peter@pcc.me.uk>
Wed, 18 Mar 2015 08:34:40 +0000 (08:34 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Wed, 18 Mar 2015 08:34:40 +0000 (08:34 +0000)
go/loader creates a fresh package map for each source package it imports. In
llgoi this caused binary imported packages to be imported anew for every input
line, resulting in spurious type errors and panics in go/ssa when encountering
previously imported types. Fix this by setting types.Config.Packages to our
internal package map.

Differential Revision: http://reviews.llvm.org/D8409

llvm-svn: 232617

llgo/cmd/llgoi/llgoi.go
llgo/irgen/compiler.go
llgo/test/llgoi/import-source.test

index e331c31..09d05e5 100644 (file)
@@ -76,8 +76,8 @@ type interp struct {
        imports []*types.Package
        scope   map[string]types.Object
 
-       pkgmap, inputPkgmap map[string]*types.Package
-       pkgnum              int
+       pkgmap map[string]*types.Package
+       pkgnum int
 }
 
 func (in *interp) makeCompilerOptions() error {
@@ -91,6 +91,7 @@ func (in *interp) makeCompilerOptions() error {
                TargetTriple:  llvm.DefaultTargetTriple(),
                ImportPaths:   importPaths,
                GenerateDebug: true,
+               Packages:      in.pkgmap,
        }
        err = in.copts.MakeImporter()
        if err != nil {
@@ -99,9 +100,6 @@ func (in *interp) makeCompilerOptions() error {
 
        origImporter := in.copts.Importer
        in.copts.Importer = func(pkgmap map[string]*types.Package, pkgpath string) (*types.Package, error) {
-               if pkg, ok := in.inputPkgmap[pkgpath]; ok {
-                       return pkg, nil
-               }
                if pkg, ok := pkgmap[pkgpath]; ok && pkg.Complete() {
                        return pkg, nil
                }
@@ -113,7 +111,6 @@ func (in *interp) makeCompilerOptions() error {
 func (in *interp) init() error {
        in.scope = make(map[string]types.Object)
        in.pkgmap = make(map[string]*types.Package)
-       in.inputPkgmap = make(map[string]*types.Package)
 
        err := in.makeCompilerOptions()
        if err != nil {
@@ -174,7 +171,7 @@ func (in *interp) loadSourcePackage(fset *token.FileSet, files []*ast.File, pkgp
                }
        }()
        importfunc()
-       in.inputPkgmap[pkgpath] = pkg
+       in.pkgmap[pkgpath] = pkg
        return
 }
 
index 36d35b7..1676921 100644 (file)
@@ -102,6 +102,9 @@ type CompilerOptions struct {
        // DisableUnusedImportCheck disables the unused import check performed
        // by go/types if set to true.
        DisableUnusedImportCheck bool
+
+       // Packages is used by go/types as the imported package map if non-nil.
+       Packages map[string]*types.Package
 }
 
 type Compiler struct {
@@ -208,8 +211,9 @@ func (compiler *compiler) compile(fset *token.FileSet, astFiles []*ast.File, imp
        impcfg := &loader.Config{
                Fset: fset,
                TypeChecker: types.Config{
-                       Import: compiler.Importer,
-                       Sizes:  compiler.llvmtypes,
+                       Packages: compiler.Packages,
+                       Import:   compiler.Importer,
+                       Sizes:    compiler.llvmtypes,
                        DisableUnusedImportCheck: compiler.DisableUnusedImportCheck,
                },
                Build:          &buildctx.Context,
index c5a3eab..b545b52 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: env GOPATH=%S/Inputs llgoi < %s | FileCheck %s
+// RUN: env GOPATH=%S/Inputs llgoi < %s 2>&1 | FileCheck %s
 
 // make sure user symbols do not conflict with imported source package
 Answer := 1
@@ -16,5 +16,15 @@ foo.Answer()
 strconv.FormatBool(true)
 // CHECK: #0 string = true
 
+var v1 strconv.NumError
+var v2 strconv.NumError
+
+// v1 and v2 should have the same type identity.
+// CHECK-NOT: cannot assign
+v1 = v2
+
+// Method lookup relies on v1 having a consistent type.
+v1.Error
+
 import "foo_cgo"
 // CHECK: foo_cgo: cannot load cgo package