forked from OSchip/llvm-project
llgoi: Fix type identity for imported binary packages.
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
This commit is contained in:
parent
d8dee1f54b
commit
38a7dde1c5
|
@ -76,8 +76,8 @@ type interp struct {
|
||||||
imports []*types.Package
|
imports []*types.Package
|
||||||
scope map[string]types.Object
|
scope map[string]types.Object
|
||||||
|
|
||||||
pkgmap, inputPkgmap map[string]*types.Package
|
pkgmap map[string]*types.Package
|
||||||
pkgnum int
|
pkgnum int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (in *interp) makeCompilerOptions() error {
|
func (in *interp) makeCompilerOptions() error {
|
||||||
|
@ -91,6 +91,7 @@ func (in *interp) makeCompilerOptions() error {
|
||||||
TargetTriple: llvm.DefaultTargetTriple(),
|
TargetTriple: llvm.DefaultTargetTriple(),
|
||||||
ImportPaths: importPaths,
|
ImportPaths: importPaths,
|
||||||
GenerateDebug: true,
|
GenerateDebug: true,
|
||||||
|
Packages: in.pkgmap,
|
||||||
}
|
}
|
||||||
err = in.copts.MakeImporter()
|
err = in.copts.MakeImporter()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -99,9 +100,6 @@ func (in *interp) makeCompilerOptions() error {
|
||||||
|
|
||||||
origImporter := in.copts.Importer
|
origImporter := in.copts.Importer
|
||||||
in.copts.Importer = func(pkgmap map[string]*types.Package, pkgpath string) (*types.Package, error) {
|
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() {
|
if pkg, ok := pkgmap[pkgpath]; ok && pkg.Complete() {
|
||||||
return pkg, nil
|
return pkg, nil
|
||||||
}
|
}
|
||||||
|
@ -113,7 +111,6 @@ func (in *interp) makeCompilerOptions() error {
|
||||||
func (in *interp) init() error {
|
func (in *interp) init() error {
|
||||||
in.scope = make(map[string]types.Object)
|
in.scope = make(map[string]types.Object)
|
||||||
in.pkgmap = make(map[string]*types.Package)
|
in.pkgmap = make(map[string]*types.Package)
|
||||||
in.inputPkgmap = make(map[string]*types.Package)
|
|
||||||
|
|
||||||
err := in.makeCompilerOptions()
|
err := in.makeCompilerOptions()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -174,7 +171,7 @@ func (in *interp) loadSourcePackage(fset *token.FileSet, files []*ast.File, pkgp
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
importfunc()
|
importfunc()
|
||||||
in.inputPkgmap[pkgpath] = pkg
|
in.pkgmap[pkgpath] = pkg
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,6 +102,9 @@ type CompilerOptions struct {
|
||||||
// DisableUnusedImportCheck disables the unused import check performed
|
// DisableUnusedImportCheck disables the unused import check performed
|
||||||
// by go/types if set to true.
|
// by go/types if set to true.
|
||||||
DisableUnusedImportCheck bool
|
DisableUnusedImportCheck bool
|
||||||
|
|
||||||
|
// Packages is used by go/types as the imported package map if non-nil.
|
||||||
|
Packages map[string]*types.Package
|
||||||
}
|
}
|
||||||
|
|
||||||
type Compiler struct {
|
type Compiler struct {
|
||||||
|
@ -208,8 +211,9 @@ func (compiler *compiler) compile(fset *token.FileSet, astFiles []*ast.File, imp
|
||||||
impcfg := &loader.Config{
|
impcfg := &loader.Config{
|
||||||
Fset: fset,
|
Fset: fset,
|
||||||
TypeChecker: types.Config{
|
TypeChecker: types.Config{
|
||||||
Import: compiler.Importer,
|
Packages: compiler.Packages,
|
||||||
Sizes: compiler.llvmtypes,
|
Import: compiler.Importer,
|
||||||
|
Sizes: compiler.llvmtypes,
|
||||||
DisableUnusedImportCheck: compiler.DisableUnusedImportCheck,
|
DisableUnusedImportCheck: compiler.DisableUnusedImportCheck,
|
||||||
},
|
},
|
||||||
Build: &buildctx.Context,
|
Build: &buildctx.Context,
|
||||||
|
|
|
@ -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
|
// make sure user symbols do not conflict with imported source package
|
||||||
Answer := 1
|
Answer := 1
|
||||||
|
@ -16,5 +16,15 @@ foo.Answer()
|
||||||
strconv.FormatBool(true)
|
strconv.FormatBool(true)
|
||||||
// CHECK: #0 string = 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"
|
import "foo_cgo"
|
||||||
// CHECK: foo_cgo: cannot load cgo package
|
// CHECK: foo_cgo: cannot load cgo package
|
||||||
|
|
Loading…
Reference in New Issue