From 36729568fbf96ea0d481344cf3ef559c74f59f95 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 18 Jul 2019 16:51:00 +0000 Subject: [PATCH] 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 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/import.cc | 20 ++++++++++++++++++++ gcc/go/gofrontend/import.h | 23 +++++++++++++++-------- gcc/go/gofrontend/statements.cc | 2 ++ 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index c5ace5accbe..ccc1a24be26 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -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. diff --git a/gcc/go/gofrontend/import.cc b/gcc/go/gofrontend/import.cc index ad7ba7fe3a4..be71f041050 100644 --- a/gcc/go/gofrontend/import.cc +++ b/gcc/go/gofrontend/import.cc @@ -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& diff --git a/gcc/go/gofrontend/import.h b/gcc/go/gofrontend/import.h index ea01bbcfb46..a78e48b7ca0 100644 --- a/gcc/go/gofrontend/import.h +++ b/gcc/go/gofrontend/import.h @@ -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 blocks_; // Current expected indentation level. int indent_; // Temporary statements by index. diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index b0b576f8cbe..27c4b95781d 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -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; -- 2.30.2