Skip to content

Commit 4df7c8d

Browse files
thanmianlancetaylor
authored andcommitted
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. Change-Id: I5a2bf9bdbc505aa9258b69381e24f21df71d12d1 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/186757 Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 19ed722 commit 4df7c8d

File tree

3 files changed

+37
-8
lines changed

3 files changed

+37
-8
lines changed

go/import.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,6 +1535,26 @@ Stream_from_file::do_advance(size_t skip)
15351535

15361536
// Class Import_function_body.
15371537

1538+
Import_function_body::Import_function_body(Gogo* gogo,
1539+
Import* imp,
1540+
Named_object* named_object,
1541+
const std::string& body,
1542+
size_t off,
1543+
Block* block,
1544+
int indent)
1545+
: gogo_(gogo), imp_(imp), named_object_(named_object), body_(body),
1546+
off_(off), indent_(indent), temporaries_(), labels_(),
1547+
saw_error_(false)
1548+
{
1549+
this->blocks_.push_back(block);
1550+
}
1551+
1552+
Import_function_body::~Import_function_body()
1553+
{
1554+
// At this point we should be left with the original outer block only.
1555+
go_assert(saw_errors() || this->blocks_.size() == 1);
1556+
}
1557+
15381558
// The name of the function we are parsing.
15391559

15401560
const std::string&

go/import.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -593,11 +593,8 @@ class Import_function_body : public Import_expression
593593
public:
594594
Import_function_body(Gogo* gogo, Import* imp, Named_object* named_object,
595595
const std::string& body, size_t off, Block* block,
596-
int indent)
597-
: gogo_(gogo), imp_(imp), named_object_(named_object), body_(body),
598-
off_(off), block_(block), indent_(indent), temporaries_(), labels_(),
599-
saw_error_(false)
600-
{ }
596+
int indent);
597+
~Import_function_body();
601598

602599
// The IR.
603600
Gogo*
@@ -637,7 +634,17 @@ class Import_function_body : public Import_expression
637634
// The current block.
638635
Block*
639636
block()
640-
{ return this->block_; }
637+
{ return this->blocks_.back(); }
638+
639+
// Begin importing a new block BLOCK nested within the current block.
640+
void
641+
begin_block(Block *block)
642+
{ this->blocks_.push_back(block); }
643+
644+
// Record the fact that we're done importing the current block.
645+
void
646+
finish_block()
647+
{ this->blocks_.pop_back(); }
641648

642649
// The current indentation.
643650
int
@@ -757,8 +764,8 @@ class Import_function_body : public Import_expression
757764
const std::string& body_;
758765
// The current offset into body_.
759766
size_t off_;
760-
// Current block.
761-
Block* block_;
767+
// Stack to record nesting of blocks being imported.
768+
std::vector<Block *> blocks_;
762769
// Current expected indentation level.
763770
int indent_;
764771
// Temporary statements by index.

go/statements.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2176,7 +2176,9 @@ Block_statement::do_import(Import_function_body* ifb, Location loc,
21762176
ifb->set_off(nl + 1);
21772177
ifb->increment_indent();
21782178
Block* block = new Block(ifb->block(), loc);
2179+
ifb->begin_block(block);
21792180
bool ok = Block::import_block(block, ifb, loc);
2181+
ifb->finish_block();
21802182
ifb->decrement_indent();
21812183
if (!ok)
21822184
return NULL;

0 commit comments

Comments
 (0)