Commit 9c81402f authored by Robert Griesemer's avatar Robert Griesemer

go/internal/gccgoimporter: fix updating of "forward declared" types

The existing code uses a type map which associates a type number
with a type; references to existing types are expressed via the
type number in the export data.

Before this CL, type map entries were set when a type was read
in completely, which meant that recursive references to types
(i.e., type map entries) that were in the middle of construction
(i.e., where the type map was not yet updated) would lead to nil
types. Such cycles are usually created via defined types which
introduce a types.Named entry into the type map before the underlying
type is parsed; in this case the code worked. In case of type aliases,
no such "forwarder" exists and type cycles lead to nil types.

This CL fixes the problem by a) updating the type map as soon as
a type becomes available but before the type's components are parsed;
b) keeping track of a list of type map entries that may need to be
updated together (because of aliases that may all refer to the same
type); and c) adding (redundant) markers to the type map to detect
algorithmic errors.

Also:
- distinguish between parseInt and parseInt64
- added more test cases

Fixes #27856.

Change-Id: Iba701439ea3231aa435b7b80ea2d419db2af3be1
Reviewed-on: https://go-review.googlesource.com/137857
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent ae9c822f
......@@ -102,8 +102,10 @@ var importerTests = [...]importerTest{
{pkgpath: "unicode", name: "MaxRune", want: "const MaxRune untyped rune", wantval: "1114111"},
{pkgpath: "imports", wantinits: []string{"imports..import", "fmt..import", "math..import"}},
{pkgpath: "importsar", name: "Hello", want: "var Hello string"},
{pkgpath: "alias", name: "IntAlias2", want: "type IntAlias2 = Int"},
{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: "escapeinfo", name: "NewT", want: "func NewT(data []byte) *T"},
{pkgpath: "issue27856", name: "M", want: "type M struct{E F}"},
}
func TestGoxImporter(t *testing.T) {
......
This diff is collapsed.
package aliases
type (
T0 [10]int
T1 []byte
T2 struct {
x int
}
T3 interface {
m() T2
}
T4 func(int, T0) chan T2
)
// basic aliases
type (
Ai = int
A0 = T0
A1 = T1
A2 = T2
A3 = T3
A4 = T4
A10 = [10]int
A11 = []byte
A12 = struct {
x int
}
A13 = interface {
m() A2
}
A14 = func(int, A0) chan A2
)
// alias receiver types
func (T0) m1() {}
func (A0) m2() {}
// alias receiver types (long type declaration chains)
type (
V0 = V1
V1 = (V2)
V2 = (V3)
V3 = T0
)
func (V1) n() {}
// cycles
type C0 struct {
f1 C1
f2 C2
}
type (
C1 *C0
C2 = C1
)
type (
C5 struct {
f *C6
}
C6 = C5
)
v2;
package aliases;
prefix go;
package aliases go.aliases go.aliases;
type <type 1 "A0" = <type 2 "T0" <type 3 [10 ] <type -11>>
func (? <esc:0x1> <type 2>) .go.aliases.m1 ();
func (? <esc:0x1> <type 1>) .go.aliases.m2 ();
func (? <esc:0x1> <type 4 "V1" = <type 5 "V2" = <type 6 "V3" = <type 2>>>>) .go.aliases.n ();
>>;
type <type 7 "A1" = <type 8 "T1" <type 9 [] <type -20>>>>;
type <type 10 "A10" = <type 11 [10 ] <type -11>>>;
type <type 12 "A11" = <type 13 [] <type -20>>>;
type <type 14 "A12" = <type 15 struct { .go.aliases.x <type -11>; }>>;
type <type 16 "A13" = <type 17 interface { .go.aliases.m () <type 18 "A2" = <type 19 "T2" <type 20 struct { .go.aliases.x <type -11>; }>>>; }>>;
type <type 21 "A14" = <type 22 (? <type -11>, ? <type 1>) <type 23 chan <type 18>>>>;
type <type 18>;
type <type 24 "A3" = <type 25 "T3" <type 26 interface { .go.aliases.m () <type 19>; }>>>;
type <type 27 "A4" = <type 28 "T4" <type 29 (? <type -11>, ? <type 2>) <type 30 chan <type 19>>>>>;
type <type 31 "Ai" = <type -11>>;
type <type 32 "C0" <type 33 struct { .go.aliases.f1 <type 34 "C1" <type 35 *<type 32>>>; .go.aliases.f2 <type 36 "C2" = <type 34>>; }>>;
type <type 34>;
type <type 36>;
type <type 37 "C5" <type 38 struct { .go.aliases.f <type 39 *<type 40 "C6" = <type 37>>>; }>>;
type <type 40>;
type <type 2>;
type <type 8>;
type <type 19>;
type <type 25>;
type <type 28>;
type <type 41 "V0" = <type 4>>;
type <type 4>;
type <type 5>;
type <type 6>;
package lib
type M struct {
E E
}
type F struct {
_ *M
}
type E = F
v2;
package main;
pkgpath main;
import runtime runtime "runtime";
init runtime runtime..import sys runtime_internal_sys..import;
init_graph 0 1;
type <type 1 "E" = <type 2 "F" <type 3 struct { .main._ <type 4 *<type 5 "M" <type 6 struct { E <type 1>; }>>>; }>>>;
type <type 2>;
type <type 5>;
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