]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
compiler: traverse method declarations
authorIan Lance Taylor <iant@golang.org>
Wed, 4 Dec 2024 04:25:47 +0000 (20:25 -0800)
committerIan Lance Taylor <iant@golang.org>
Wed, 4 Dec 2024 23:20:05 +0000 (15:20 -0800)
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
gcc/go/gofrontend/gogo.cc

index 3bd755ce515ed5df9bff761e972654d6ca1b076e..d189a9c6df057fce32ba88b810157e972cee997d 100644 (file)
@@ -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.
index 8a833761a5fd7faab6fa0a266726f785ac10747d..3aad4194c628920d59026e259a2037acd0ac1716 100644 (file)
@@ -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: