https://gcc.gnu.org/g:9a53561075d7c2655d5fb6844c5493023b9bb813
commit r15-5929-g9a53561075d7c2655d5fb6844c5493023b9bb813 Author: Ian Lance Taylor <i...@golang.org> Date: Tue Dec 3 20:25:47 2024 -0800 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 Diff: --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/gogo.cc | 50 +++++++++++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 3bd755ce515e..d189a9c6df05 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -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. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 8a833761a5fd..3aad4194c628 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -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: