This Go frontend patch by Than McIntosh  fixes a buglet in the
function body importer.  It adds 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.

There is a new test case for this problem in https://golang.org/cl/186717.

This fixes https://golang.org/issue/33158.

Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
to mainline.

Ian
Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE     (revision 273564)
+++ gcc/go/gofrontend/MERGE     (working copy)
@@ -1,4 +1,4 @@
-19ed722fb3ae5e618c746da20efb79fc837337cd
+4df7c8d7af894ee93f50c3a50debdcf4e369a2c6
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: gcc/go/gofrontend/import.cc
===================================================================
--- gcc/go/gofrontend/import.cc (revision 273534)
+++ gcc/go/gofrontend/import.cc (working copy)
@@ -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&
Index: gcc/go/gofrontend/import.h
===================================================================
--- gcc/go/gofrontend/import.h  (revision 273534)
+++ gcc/go/gofrontend/import.h  (working copy)
@@ -593,11 +593,8 @@ class Import_function_body : public Impo
  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 Impo
   // 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 Impo
   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.
Index: gcc/go/gofrontend/statements.cc
===================================================================
--- gcc/go/gofrontend/statements.cc     (revision 273534)
+++ gcc/go/gofrontend/statements.cc     (working copy)
@@ -2176,7 +2176,9 @@ Block_statement::do_import(Import_functi
   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;

Reply via email to