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:

Reply via email to