Skip to content

Commit

Permalink
compiler: Don't record dependencies of invalid redefinitions.
Browse files Browse the repository at this point in the history
    
    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
  • Loading branch information
ian committed Aug 27, 2015
1 parent a5bc39b commit 8416894
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 2 deletions.
2 changes: 1 addition & 1 deletion gcc/go/gofrontend/MERGE
Original file line number Diff line number Diff line change
@@ -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.
5 changes: 4 additions & 1 deletion gcc/go/gofrontend/gogo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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());
Expand Down
13 changes: 13 additions & 0 deletions gcc/go/gofrontend/gogo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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.
Expand Down
8 changes: 8 additions & 0 deletions gcc/go/gofrontend/parse.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 8416894

Please sign in to comment.