Commit 36729568 by Ian Lance Taylor

compiler: fix bug in importing blocks from inline functions

    
    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.
    
    Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/186757

From-SVN: r273577
parent a6fc663e
19ed722fb3ae5e618c746da20efb79fc837337cd
4df7c8d7af894ee93f50c3a50debdcf4e369a2c6
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
......@@ -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&
......
......@@ -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*
......@@ -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
......@@ -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.
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment