Skip to content

Commit

Permalink
compiler: fix bug in importing blocks from inline functions
Browse files Browse the repository at this point in the history
This patch fixes a buglet in the function body importer. Add hooks for
keeping a stack of blocks corresponding to the block nesting in the
imported function. This ensures that local variables and temps wind up
correctly scoped and don't introduce collisions.

New test case for this problem in CL 186717.

Fixes golang/go#33158.

Change-Id: I5a2bf9bdbc505aa9258b69381e24f21df71d12d1
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/186757
Reviewed-by: Ian Lance Taylor <iant@golang.org>
  • Loading branch information
thanm authored and ianlancetaylor committed Jul 18, 2019
1 parent 19ed722 commit 4df7c8d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 8 deletions.
20 changes: 20 additions & 0 deletions go/import.cc
Expand Up @@ -1535,6 +1535,26 @@ Stream_from_file::do_advance(size_t skip)

// Class Import_function_body.

Import_function_body::Import_function_body(Gogo* gogo,
Import* imp,
Named_object* named_object,
const std::string& body,
size_t off,
Block* block,
int indent)
: gogo_(gogo), imp_(imp), named_object_(named_object), body_(body),
off_(off), indent_(indent), temporaries_(), labels_(),
saw_error_(false)
{
this->blocks_.push_back(block);
}

Import_function_body::~Import_function_body()
{
// At this point we should be left with the original outer block only.
go_assert(saw_errors() || this->blocks_.size() == 1);
}

// The name of the function we are parsing.

const std::string&
Expand Down
23 changes: 15 additions & 8 deletions go/import.h
Expand Up @@ -593,11 +593,8 @@ class Import_function_body : public Import_expression
public:
Import_function_body(Gogo* gogo, Import* imp, Named_object* named_object,
const std::string& body, size_t off, Block* block,
int indent)
: gogo_(gogo), imp_(imp), named_object_(named_object), body_(body),
off_(off), block_(block), indent_(indent), temporaries_(), labels_(),
saw_error_(false)
{ }
int indent);
~Import_function_body();

// The IR.
Gogo*
Expand Down Expand Up @@ -637,7 +634,17 @@ class Import_function_body : public Import_expression
// The current block.
Block*
block()
{ return this->block_; }
{ return this->blocks_.back(); }

// Begin importing a new block BLOCK nested within the current block.
void
begin_block(Block *block)
{ this->blocks_.push_back(block); }

// Record the fact that we're done importing the current block.
void
finish_block()
{ this->blocks_.pop_back(); }

// The current indentation.
int
Expand Down Expand Up @@ -757,8 +764,8 @@ class Import_function_body : public Import_expression
const std::string& body_;
// The current offset into body_.
size_t off_;
// Current block.
Block* block_;
// Stack to record nesting of blocks being imported.
std::vector<Block *> blocks_;
// Current expected indentation level.
int indent_;
// Temporary statements by index.
Expand Down
2 changes: 2 additions & 0 deletions go/statements.cc
Expand Up @@ -2176,7 +2176,9 @@ Block_statement::do_import(Import_function_body* ifb, Location loc,
ifb->set_off(nl + 1);
ifb->increment_indent();
Block* block = new Block(ifb->block(), loc);
ifb->begin_block(block);
bool ok = Block::import_block(block, ifb, loc);
ifb->finish_block();
ifb->decrement_indent();
if (!ok)
return NULL;
Expand Down

0 comments on commit 4df7c8d

Please sign in to comment.