go/gcimporter15: backport of https://golang.org/cl/23012/

Fixes golang/go#16365.

Change-Id: I8e33fbd9f1bf1b4b5d85a5c972ad43414cea57cb
Reviewed-on: https://go-review.googlesource.com/24973
Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
Robert Griesemer 2016-07-15 14:16:42 -07:00
parent ffe4e61c64
commit 3f933d433a
4 changed files with 54 additions and 2 deletions

View File

@ -181,7 +181,7 @@ func (p *importer) declare(obj types.Object) {
// imported.
// (See also the comment in cmd/compile/internal/gc/bimport.go importer.obj,
// switch case importing functions).
panic(fmt.Sprintf("%s already declared", alt.Name()))
panic(fmt.Sprintf("inconsistent import:\n\t%v\npreviously imported as:\n\t%v\n", alt, obj))
}
}

View File

@ -175,7 +175,7 @@ func Import(packages map[string]*types.Package, path, srcDir string) (pkg *types
data, err = ioutil.ReadAll(buf)
if err == nil {
fset := token.NewFileSet()
_, pkg, err = BImportData(fset, packages, data, path)
_, pkg, err = BImportData(fset, packages, data, id)
return
}
default:

View File

@ -363,3 +363,42 @@ func TestIssue13898(t *testing.T) {
t.Fatalf("found %v; want go/types", m.Pkg())
}
}
func TestIssue15517(t *testing.T) {
skipSpecialPlatforms(t)
// This package only handles gc export data.
if runtime.Compiler != "gc" {
t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
return
}
// On windows, we have to set the -D option for the compiler to avoid having a drive
// letter and an illegal ':' in the import path - just skip it (see also issue #3483).
if runtime.GOOS == "windows" {
t.Skip("avoid dealing with relative paths/drive letters on windows")
}
if f := compile(t, "testdata", "p.go"); f != "" {
defer os.Remove(f)
}
// Multiple imports of p must succeed without redeclaration errors.
// We use an import path that's not cleaned up so that the eventual
// file path for the package is different from the package path; this
// will expose the error if it is present.
//
// (Issue: Both the textual and the binary importer used the file path
// of the package to be imported as key into the shared packages map.
// However, the binary importer then used the package path to identify
// the imported package to mark it as complete; effectively marking the
// wrong package as complete. By using an "unclean" package path, the
// file and package path are different, exposing the problem if present.
// The same issue occurs with vendoring.)
imports := make(map[string]*types.Package)
for i := 0; i < 3; i++ {
if _, err := Import(imports, "./././testdata/p", "."); err != nil {
t.Fatal(err)
}
}
}

13
go/gcimporter15/testdata/p.go vendored Normal file
View File

@ -0,0 +1,13 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Input for TestIssue15517
package p
const C = 0
var V int
func F() {}