diff options
author | Ian Lance Taylor <iant@golang.org> | 2024-12-03 20:25:47 -0800 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2024-12-04 15:20:05 -0800 |
commit | 9a53561075d7c2655d5fb6844c5493023b9bb813 (patch) | |
tree | 7565bd60a9c16a875f7455b058bde0a3d737e910 /gcc/go | |
parent | 2576dd68a60b3f317f89c8c007d0eea63151a793 (diff) | |
download | gcc-9a53561075d7c2655d5fb6844c5493023b9bb813.zip gcc-9a53561075d7c2655d5fb6844c5493023b9bb813.tar.gz gcc-9a53561075d7c2655d5fb6844c5493023b9bb813.tar.bz2 |
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
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | 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 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: |