compiler: track placeholder pointer types for conversion
authorIan Lance Taylor <ian@gcc.gnu.org>
Fri, 28 Jul 2017 18:03:29 +0000 (18:03 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Fri, 28 Jul 2017 18:03:29 +0000 (18:03 +0000)
    We recently started walking through the hash table of pointer types to
    finalize them.  Unfortunately it is possible to create a new pointer
    type while finalizing an existing one (test case: test/fixedbugs/issue5291)
    and that breaks the iteration.  So, instead, keep a list of
    placeholder pointer types, and iterate through them while permitting
    the list to be extended as we go.

    Reviewed-on: https://go-review.googlesource.com/51771

From-SVN: r250683

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

index 1c649cb6ca95e4716d213bf67530e2dcfcd5c876..9dc96cfc1000be581706aa8bc53edfc96090cd7c 100644 (file)
@@ -1,4 +1,4 @@
-27804ec53590e3644e030c9860822139a0cfb03f
+2118958321532352c91fd9406f571f8729a791cd
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index 91d6091f54496031eba8a383ad722c2c3a0a9d82..4d923733667ff9d45338e87b892918ae3b194bac 100644 (file)
@@ -1057,6 +1057,8 @@ Type::get_backend_placeholder(Gogo* gogo)
       {
        Location loc = Linemap::unknown_location();
        bt = gogo->backend()->placeholder_pointer_type("", loc, false);
+       Pointer_type* pt = this->convert<Pointer_type, TYPE_POINTER>();
+       Type::placeholder_pointers.push_back(pt);
       }
       break;
 
@@ -5521,6 +5523,11 @@ Pointer_type::do_import(Import* imp)
 
 Type::Pointer_type_table Type::pointer_types;
 
+// A list of placeholder pointer types.  We keep this so we can ensure
+// they are finalized.
+
+std::vector<Pointer_type*> Type::placeholder_pointers;
+
 // Make a pointer type.
 
 Pointer_type*
@@ -5551,11 +5558,11 @@ Type::make_pointer_type(Type* to_type)
 void
 Type::finish_pointer_types(Gogo* gogo)
 {
-  for (Pointer_type_table::const_iterator i = pointer_types.begin();
-       i != pointer_types.end();
-       ++i)
+  // We don't use begin() and end() because it is possible to add new
+  // placeholder pointer types as we finalized existing ones.
+  for (size_t i = 0; i < Type::placeholder_pointers.size(); i++)
     {
-      Pointer_type* pt = i->second;
+      Pointer_type* pt = Type::placeholder_pointers[i];
       Type_btypes::iterator tbti = Type::type_btypes.find(pt);
       if (tbti != Type::type_btypes.end() && tbti->second.is_placeholder)
         {
index f659f3848456fb0187e5f33c2a37bca01e0c07fd..f15f08ae4f086bfb4655019b4739e062cbc44f2f 100644 (file)
@@ -1350,6 +1350,9 @@ class Type
 
   static Pointer_type_table pointer_types;
 
+  // List of placeholder pointer types.
+  static std::vector<Pointer_type*> placeholder_pointers;
+
   // The type classification.
   Type_classification classification_;
   // The backend representation of the type, once it has been