summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2015-08-27 19:06:59 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2015-08-27 19:06:59 +0000
commit8416894787605a641b2831f97e3830d848c2facf (patch)
tree0d00f5f3ee3e684213177e8eb0fba4954e1b391b
parenta5bc39b79b2c348c1411cbd15b7e1b17d8634dd9 (diff)
downloadgcc-8416894787605a641b2831f97e3830d848c2facf.tar.gz
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 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@227276 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/gogo.cc5
-rw-r--r--gcc/go/gofrontend/gogo.h13
-rw-r--r--gcc/go/gofrontend/parse.cc8
4 files changed, 26 insertions, 2 deletions
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