]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
compiler: Fix bug in embedded method handling.
authorIan Lance Taylor <ian@gcc.gnu.org>
Tue, 6 May 2014 05:33:31 +0000 (05:33 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Tue, 6 May 2014 05:33:31 +0000 (05:33 +0000)
If the same type was embedded in a struct at different levels,
only the first embedded instance was considered when building
the set of all methods.  A second instance was ignored, even
if it was at a higher level and should therefore override the
first instance.

Test case is bug485.go in master repository.

From-SVN: r210096

gcc/go/gofrontend/types.cc
gcc/go/gofrontend/types.h

index 0ff9c76d68b1580dc4c13ba7fe9131797e9e5db3..096d87288d485d01bf338d7019d638186825aebc 100644 (file)
@@ -8924,9 +8924,8 @@ Type::finalize_methods(Gogo* gogo, const Type* type, Location location,
                       Methods** all_methods)
 {
   *all_methods = NULL;
-  Types_seen types_seen;
-  Type::add_methods_for_type(type, NULL, 0, false, false, &types_seen,
-                            all_methods);
+  std::vector<const Named_type*> seen;
+  Type::add_methods_for_type(type, NULL, 0, false, false, &seen, all_methods);
   Type::build_stub_methods(gogo, type, *all_methods, location);
 }
 
@@ -8944,7 +8943,7 @@ Type::add_methods_for_type(const Type* type,
                           unsigned int depth,
                           bool is_embedded_pointer,
                           bool needs_stub_method,
-                          Types_seen* types_seen,
+                          std::vector<const Named_type*>* seen,
                           Methods** methods)
 {
   // Pointer types may not have methods.
@@ -8954,19 +8953,24 @@ Type::add_methods_for_type(const Type* type,
   const Named_type* nt = type->named_type();
   if (nt != NULL)
     {
-      std::pair<Types_seen::iterator, bool> ins = types_seen->insert(nt);
-      if (!ins.second)
-       return;
-    }
+      for (std::vector<const Named_type*>::const_iterator p = seen->begin();
+          p != seen->end();
+          ++p)
+       {
+         if (*p == nt)
+           return;
+       }
 
-  if (nt != NULL)
-    Type::add_local_methods_for_type(nt, field_indexes, depth,
-                                    is_embedded_pointer, needs_stub_method,
-                                    methods);
+      seen->push_back(nt);
+
+      Type::add_local_methods_for_type(nt, field_indexes, depth,
+                                      is_embedded_pointer, needs_stub_method,
+                                      methods);
+    }
 
   Type::add_embedded_methods_for_type(type, field_indexes, depth,
                                      is_embedded_pointer, needs_stub_method,
-                                     types_seen, methods);
+                                     seen, methods);
 
   // If we are called with depth > 0, then we are looking at an
   // anonymous field of a struct.  If such a field has interface type,
@@ -8975,6 +8979,9 @@ Type::add_methods_for_type(const Type* type,
   // following the usual rules for an interface type.
   if (depth > 0)
     Type::add_interface_methods_for_type(type, field_indexes, depth, methods);
+
+  if (nt != NULL)
+      seen->pop_back();
 }
 
 // Add the local methods for the named type NT to *METHODS.  The
@@ -9020,7 +9027,7 @@ Type::add_embedded_methods_for_type(const Type* type,
                                    unsigned int depth,
                                    bool is_embedded_pointer,
                                    bool needs_stub_method,
-                                   Types_seen* types_seen,
+                                   std::vector<const Named_type*>* seen,
                                    Methods** methods)
 {
   // Look for anonymous fields in TYPE.  TYPE has fields if it is a
@@ -9064,7 +9071,7 @@ Type::add_embedded_methods_for_type(const Type* type,
                                 (needs_stub_method
                                  || is_pointer
                                  || i > 0),
-                                types_seen,
+                                seen,
                                 methods);
     }
 }
index b2a49ac3af11ccebbb54e5ac9f575e56702304c3..e6ba995429fc65e561cb6fb96e8076bf9024c01f 100644 (file)
@@ -1171,14 +1171,11 @@ class Type
   static tree
   build_receive_return_type(tree type);
 
-  // A hash table we use to avoid infinite recursion.
-  typedef Unordered_set_hash(const Named_type*, Type_hash_identical,
-                            Type_identical) Types_seen;
-
   // Add all methods for TYPE to the list of methods for THIS.
   static void
   add_methods_for_type(const Type* type, const Method::Field_indexes*,
-                      unsigned int depth, bool, bool, Types_seen*,
+                      unsigned int depth, bool, bool,
+                      std::vector<const Named_type*>*,
                       Methods**);
 
   static void
@@ -1189,7 +1186,8 @@ class Type
   static void
   add_embedded_methods_for_type(const Type* type,
                                const Method::Field_indexes*,
-                               unsigned int depth, bool, bool, Types_seen*,
+                               unsigned int depth, bool, bool,
+                               std::vector<const Named_type*>*,
                                Methods**);
 
   static void