compiler: finalize types parsed for inline functions
authorIan Lance Taylor <ian@gcc.gnu.org>
Tue, 27 Nov 2018 21:34:44 +0000 (21:34 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Tue, 27 Nov 2018 21:34:44 +0000 (21:34 +0000)
    When we inline functions, we may parse types that we have not seen
    before inlining.  Inlining runs after the finalize_methods pass, so
    those types will not be finalized, meaning that we don't have an
    accurate list of which methods they support.  Explicitly finalize them
    when we parse them.

    Reviewed-on: https://go-review.googlesource.com/c/150068

From-SVN: r266530

gcc/go/gofrontend/MERGE
gcc/go/gofrontend/gogo.cc
gcc/go/gofrontend/gogo.h
gcc/go/gofrontend/import.cc
gcc/go/gofrontend/import.h

index 3f87798749c568265341dcbd83d6b5f477719eac..9947fcf68a1826e018afd67d0bce51fd0bbbc555 100644 (file)
@@ -1,4 +1,4 @@
-ce81aad0e3d53215e2c0f1f060c7fd6219e6fb23
+c11d9528a0846293e4d615c86fc773c97252fdce
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index eb0297bc2db379ee96af9c4405647eedc3c9eb00..a5a0e5620d31da10c3be45a347e282b5d834103c 100644 (file)
@@ -3243,6 +3243,17 @@ Gogo::finalize_methods()
   this->traverse(&finalize);
 }
 
+// Finalize the method list for a type.  This is called when a type is
+// parsed for an inlined function body, which happens after the
+// finalize_methods pass.
+
+void
+Gogo::finalize_methods_for_type(Type* type)
+{
+  Finalize_methods finalize(this);
+  Type::traverse(type, &finalize);
+}
+
 // Set types for unspecified variables and constants.
 
 void
index 8ca567ca13c1a0cb7727a32122e1cb5bc55d3acd..854d37a6333391e70e203a49a8c45111e870ce78 100644 (file)
@@ -637,6 +637,10 @@ class Gogo
   void
   finalize_methods();
 
+  // Finalize the method list for one type.
+  void
+  finalize_methods_for_type(Type*);
+
   // Work out the types to use for unspecified variables and
   // constants.
   void
index 524e739f21c3c3b3085ef9ecc421214e74bb2725..eefee7cb1e62402586adc0feeae14dcced715e07 100644 (file)
@@ -886,7 +886,9 @@ Import::read_type()
   if (c == '>')
     {
       // A reference to a type defined earlier.
-      return this->type_for_index(index, "import data", stream->pos());
+      bool parsed;
+      return this->type_for_index(index, "import data", stream->pos(),
+                                 &parsed);
     }
 
   if (this->version_ >= EXPORT_FORMAT_V3)
@@ -1092,12 +1094,13 @@ Import::read_named_type(int index)
   return type;
 }
 
-// Return the type given an index.
+// Return the type given an index.  Set *PARSED if we parsed it here.
 
 Type*
 Import::type_for_index(int index, const std::string& input_name,
-                      size_t input_offset)
+                      size_t input_offset, bool* parsed)
 {
+  *parsed = false;
   if (index >= 0 && !this->type_data_.empty())
     {
       if (static_cast<size_t>(index) >= this->type_offsets_.size())
@@ -1114,6 +1117,7 @@ Import::type_for_index(int index, const std::string& input_name,
        {
          if (!this->parse_type(index))
            return Type::make_error_type();
+         *parsed = true;
        }
     }
 
@@ -1497,6 +1501,15 @@ Import_function_body::read_type()
       return Type::make_error_type();
     }
 
-  return this->imp_->type_for_index(static_cast<int>(val), this->name(),
-                                   static_cast<unsigned long>(start));
+  bool parsed;
+  Type* type = this->imp_->type_for_index(static_cast<int>(val), this->name(),
+                                         static_cast<unsigned long>(start),
+                                         &parsed);
+
+  // If we just read this type's information, its methods will not
+  // have been finalized.  Do that now.
+  if (parsed)
+    this->gogo_->finalize_methods_for_type(type);
+
+  return type;
 }
index 948cdf7552faf790176c92ad422eec66e0994210..e2f4e50378ca79c2f2aeb98e537068d76d840d45 100644 (file)
@@ -284,10 +284,11 @@ class Import : public Import_expression
   read_type();
 
   // Return the type for a type index.  INPUT_NAME and INPUT_OFFSET
-  // are only for error reporting.
+  // are only for error reporting.  PARSED is set to whether we parsed
+  // the type information for a new type.
   Type*
   type_for_index(int index, const std::string& input_name,
-                size_t input_offset);
+                size_t input_offset, bool* parsed);
 
   // Read an escape note.
   std::string