From: Ian Lance Taylor Date: Thu, 27 Aug 2015 19:06:59 +0000 (+0000) Subject: compiler: Don't record dependencies of invalid redefinitions. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=31da952a49ef2861ee35786a3e41865ac259599c;p=gcc.git compiler: Don't record dependencies of invalid redefinitions. 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 --- diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index f29ffd4c71e..4561966046c 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -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. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 134e0379461..ea9104fc3c3 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -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()); diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index ece7e0f2e1c..374f155e05d 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -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. diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc index 922473ac810..cc4377627e9 100644 --- a/gcc/go/gofrontend/parse.cc +++ b/gcc/go/gofrontend/parse.cc @@ -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