compiler: Fix bug in embedded method handling.
If the same type was embedded in a struct at different levels, only the first embedded instance was considered when building the set of all methods. A second instance was ignored, even if it was at a higher level and should therefore override the first instance. Test case is bug485.go in master repository. From-SVN: r210096
This commit is contained in:
parent
0c2b1bb7b6
commit
6f07319115
@ -8924,9 +8924,8 @@ Type::finalize_methods(Gogo* gogo, const Type* type, Location location,
|
||||
Methods** all_methods)
|
||||
{
|
||||
*all_methods = NULL;
|
||||
Types_seen types_seen;
|
||||
Type::add_methods_for_type(type, NULL, 0, false, false, &types_seen,
|
||||
all_methods);
|
||||
std::vector<const Named_type*> seen;
|
||||
Type::add_methods_for_type(type, NULL, 0, false, false, &seen, all_methods);
|
||||
Type::build_stub_methods(gogo, type, *all_methods, location);
|
||||
}
|
||||
|
||||
@ -8944,7 +8943,7 @@ Type::add_methods_for_type(const Type* type,
|
||||
unsigned int depth,
|
||||
bool is_embedded_pointer,
|
||||
bool needs_stub_method,
|
||||
Types_seen* types_seen,
|
||||
std::vector<const Named_type*>* seen,
|
||||
Methods** methods)
|
||||
{
|
||||
// Pointer types may not have methods.
|
||||
@ -8954,19 +8953,24 @@ Type::add_methods_for_type(const Type* type,
|
||||
const Named_type* nt = type->named_type();
|
||||
if (nt != NULL)
|
||||
{
|
||||
std::pair<Types_seen::iterator, bool> ins = types_seen->insert(nt);
|
||||
if (!ins.second)
|
||||
return;
|
||||
}
|
||||
for (std::vector<const Named_type*>::const_iterator p = seen->begin();
|
||||
p != seen->end();
|
||||
++p)
|
||||
{
|
||||
if (*p == nt)
|
||||
return;
|
||||
}
|
||||
|
||||
if (nt != NULL)
|
||||
Type::add_local_methods_for_type(nt, field_indexes, depth,
|
||||
is_embedded_pointer, needs_stub_method,
|
||||
methods);
|
||||
seen->push_back(nt);
|
||||
|
||||
Type::add_local_methods_for_type(nt, field_indexes, depth,
|
||||
is_embedded_pointer, needs_stub_method,
|
||||
methods);
|
||||
}
|
||||
|
||||
Type::add_embedded_methods_for_type(type, field_indexes, depth,
|
||||
is_embedded_pointer, needs_stub_method,
|
||||
types_seen, methods);
|
||||
seen, methods);
|
||||
|
||||
// If we are called with depth > 0, then we are looking at an
|
||||
// anonymous field of a struct. If such a field has interface type,
|
||||
@ -8975,6 +8979,9 @@ Type::add_methods_for_type(const Type* type,
|
||||
// following the usual rules for an interface type.
|
||||
if (depth > 0)
|
||||
Type::add_interface_methods_for_type(type, field_indexes, depth, methods);
|
||||
|
||||
if (nt != NULL)
|
||||
seen->pop_back();
|
||||
}
|
||||
|
||||
// Add the local methods for the named type NT to *METHODS. The
|
||||
@ -9020,7 +9027,7 @@ Type::add_embedded_methods_for_type(const Type* type,
|
||||
unsigned int depth,
|
||||
bool is_embedded_pointer,
|
||||
bool needs_stub_method,
|
||||
Types_seen* types_seen,
|
||||
std::vector<const Named_type*>* seen,
|
||||
Methods** methods)
|
||||
{
|
||||
// Look for anonymous fields in TYPE. TYPE has fields if it is a
|
||||
@ -9064,7 +9071,7 @@ Type::add_embedded_methods_for_type(const Type* type,
|
||||
(needs_stub_method
|
||||
|| is_pointer
|
||||
|| i > 0),
|
||||
types_seen,
|
||||
seen,
|
||||
methods);
|
||||
}
|
||||
}
|
||||
|
@ -1171,14 +1171,11 @@ class Type
|
||||
static tree
|
||||
build_receive_return_type(tree type);
|
||||
|
||||
// A hash table we use to avoid infinite recursion.
|
||||
typedef Unordered_set_hash(const Named_type*, Type_hash_identical,
|
||||
Type_identical) Types_seen;
|
||||
|
||||
// Add all methods for TYPE to the list of methods for THIS.
|
||||
static void
|
||||
add_methods_for_type(const Type* type, const Method::Field_indexes*,
|
||||
unsigned int depth, bool, bool, Types_seen*,
|
||||
unsigned int depth, bool, bool,
|
||||
std::vector<const Named_type*>*,
|
||||
Methods**);
|
||||
|
||||
static void
|
||||
@ -1189,7 +1186,8 @@ class Type
|
||||
static void
|
||||
add_embedded_methods_for_type(const Type* type,
|
||||
const Method::Field_indexes*,
|
||||
unsigned int depth, bool, bool, Types_seen*,
|
||||
unsigned int depth, bool, bool,
|
||||
std::vector<const Named_type*>*,
|
||||
Methods**);
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user