compiler: Don't record dependencies of invalid redefinitions.
authorIan Lance Taylor <ian@gcc.gnu.org>
Thu, 27 Aug 2015 19:06:59 +0000 (19:06 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 27 Aug 2015 19:06:59 +0000 (19:06 +0000)
    The gofrontend would crash when trying to find the initialization
    order of a variable list where one of the listed variables was an
    invalid redefinition of another in a call statement.  This patch
    fixes initialization from call statements to consider invalid
    redefinitions before recording dependency information.

    Fixes golang/go#11543.

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

From-SVN: r227276

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

index f29ffd4c71e7ae9c4788d30e55ef87a131cf6597..4561966046c22dfaa9c0af49a971912dd425b808 100644 (file)
@@ -1,4 +1,4 @@
-5ee78e7d52a4cad0b23f5bc62e5b452489243c70
+a1d2cac484f46068b5a6ddf3e041d425a3d25e0c
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index 134e03794619ee121c22a818361d02c8c7ba459d..ea9104fc3c3b9db9c2a53bac2ce1a7dada3a4e63 100644 (file)
@@ -6753,7 +6753,8 @@ Unknown_name::set_real_named_object(Named_object* no)
 Named_object::Named_object(const std::string& name,
                           const Package* package,
                           Classification classification)
-  : name_(name), package_(package), classification_(classification)
+  : name_(name), package_(package), classification_(classification),
+    is_redefinition_(false)
 {
   if (Gogo::is_sink_name(name))
     go_assert(classification == NAMED_OBJECT_SINK);
@@ -7439,6 +7440,8 @@ Bindings::new_definition(Named_object* old_object, Named_object* new_object)
   else
     error_at(new_object->location(), "redefinition of %qs: %s", n.c_str(),
             reason.c_str());
+  old_object->set_is_redefinition();
+  new_object->set_is_redefinition();
 
   inform(old_object->location(), "previous definition of %qs was here",
         n.c_str());
index ece7e0f2e1ce356da26bfb916cd338fa75df6a7b..374f155e05d9e79433ab4d0f5210af4485c38cdb 100644 (file)
@@ -2389,6 +2389,17 @@ class Named_object
   void
   export_named_object(Export*) const;
 
+  // Mark this named object as an invalid redefinition of another object.
+  void
+  set_is_redefinition()
+  { this->is_redefinition_ = true; }
+
+  // Return whether or not this object is a invalid redefinition of another
+  // object.
+  bool
+  is_redefinition() const
+  { return this->is_redefinition_; }
+
  private:
   Named_object(const std::string&, const Package*, Classification);
 
@@ -2412,6 +2423,8 @@ class Named_object
     Function_declaration* func_declaration_value;
     Package* package_value;
   } u_;
+  // True if this object is an invalid redefinition of another object.
+  bool is_redefinition_;
 };
 
 // A binding contour.  This binds names to objects.
index 922473ac810358b45442be07c6632e13489c0477..cc4377627e90da187ee57d09e3b282c603050d47 100644 (file)
@@ -1741,6 +1741,14 @@ Parse::init_vars_from_call(const Typed_identifier_list* vars, Type* type,
            first_var = no;
          else
            {
+              // If the current object is a redefinition of another object, we
+              // might have already recorded the dependency relationship between
+              // it and the first variable.  Either way, an error will be
+              // reported for the redefinition and we don't need to properly
+              // record dependency information for an invalid program.
+              if (no->is_redefinition())
+                continue;
+
              // The subsequent vars have an implicit dependency on
              // the first one, so that everything gets initialized in
              // the right order and so that we detect cycles