aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2024-12-03 20:25:47 -0800
committerIan Lance Taylor <iant@golang.org>2024-12-04 15:20:05 -0800
commit9a53561075d7c2655d5fb6844c5493023b9bb813 (patch)
tree7565bd60a9c16a875f7455b058bde0a3d737e910 /gcc/go
parent2576dd68a60b3f317f89c8c007d0eea63151a793 (diff)
downloadgcc-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/MERGE2
-rw-r--r--gcc/go/gofrontend/gogo.cc50
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: