From 9a53561075d7c2655d5fb6844c5493023b9bb813 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 3 Dec 2024 20:25:47 -0800 Subject: 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 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/gogo.cc | 50 +++++++++++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 22 deletions(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 3bd755c..d189a9c 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 8a83376..3aad419 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: -- cgit v1.1