compiler: traverse method declarations
We were not consistently traversing method declarations, which appear if there is a method without a body. The gc compiler rejects that case, but gofrontend currently permits it. Maybe that should change, but not today. This avoids a compiler crash if there are method declarations with types that require specific functions. I didn't bother with a test case because a program with method declarations is almost certainly invalid anyhow. Fixes PR go/117891 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/633495
This commit is contained in:
parent
2576dd68a6
commit
9a53561075
2 changed files with 30 additions and 22 deletions
|
@ -1,4 +1,4 @@
|
|||
dfe585bf82380630697e96c249de825c5f655afe
|
||||
f4956f807f1a33e406cf1b3bf3479a9ac1c1015a
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the gofrontend repository.
|
||||
|
|
|
@ -3592,26 +3592,6 @@ Finalize_methods::type(Type* t)
|
|||
}
|
||||
}
|
||||
|
||||
// Finalize the types of all methods that are declared but not
|
||||
// defined, since we won't see the declarations otherwise.
|
||||
if (nt->named_object()->package() == NULL
|
||||
&& nt->local_methods() != NULL)
|
||||
{
|
||||
const Bindings* methods = nt->local_methods();
|
||||
for (Bindings::const_declarations_iterator p =
|
||||
methods->begin_declarations();
|
||||
p != methods->end_declarations();
|
||||
p++)
|
||||
{
|
||||
if (p->second->is_function_declaration())
|
||||
{
|
||||
Type* mt = p->second->func_declaration_value()->type();
|
||||
if (Type::traverse(mt, this) == TRAVERSE_EXIT)
|
||||
return TRAVERSE_EXIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRAVERSE_SKIP_COMPONENTS;
|
||||
}
|
||||
|
||||
|
@ -8790,7 +8770,35 @@ Named_object::traverse(Traverse* traverse, bool is_global)
|
|||
|
||||
case Named_object::NAMED_OBJECT_TYPE:
|
||||
if ((traverse_mask & e_or_t) != 0)
|
||||
t = Type::traverse(this->type_value(), traverse);
|
||||
{
|
||||
t = Type::traverse(this->type_value(), traverse);
|
||||
if (t == TRAVERSE_EXIT)
|
||||
return TRAVERSE_EXIT;
|
||||
|
||||
// Traverse the types of any local methods that are declared
|
||||
// but not defined. We will see defined methods as
|
||||
// NAMED_OBJECT_FUNC, but we won't see methods that are only
|
||||
// declared.
|
||||
if (this->package_ == NULL
|
||||
&& this->type_value()->named_type()->local_methods() != NULL)
|
||||
{
|
||||
const Bindings* methods =
|
||||
this->type_value()->named_type()->local_methods();
|
||||
for (Bindings::const_declarations_iterator p =
|
||||
methods->begin_declarations();
|
||||
p != methods->end_declarations();
|
||||
++p)
|
||||
{
|
||||
if (p->second->is_function_declaration())
|
||||
{
|
||||
Type* mt = p->second->func_declaration_value()->type();
|
||||
if (Type::traverse(mt, traverse) == TRAVERSE_EXIT)
|
||||
return TRAVERSE_EXIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Named_object::NAMED_OBJECT_PACKAGE:
|
||||
|
|
Loading…
Add table
Reference in a new issue