===================================================================
@@ -1,4 +1,4 @@
-1d8d834b5eb9f683cc06529145b353bb5b08e7ea
+8aca265d317059ae6d9721a4a231895d80d0a82c
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
===================================================================
@@ -3616,11 +3616,21 @@ Order_eval::statement(Block* block, size
// be handled specially. We can't create a temporary
// because there is no type to give it. Any actual uses of
// the values will be done via Call_result_expressions.
- s = Statement::make_statement(*pexpr, true);
- }
+ //
+ // Since a given call expression can be shared by multiple
+ // Call_result_expressions, avoid hoisting the call the
+ // second time we see it here.
+ if (this->remember_expression(*pexpr))
+ s = NULL;
+ else
+ s = Statement::make_statement(*pexpr, true);
+ }
- block->insert_statement_before(*pindex, s);
- ++*pindex;
+ if (s != NULL)
+ {
+ block->insert_statement_before(*pindex, s);
+ ++*pindex;
+ }
}
if (init != orig_init)
@@ -7949,13 +7959,14 @@ Traverse::remember_type(const Type* type
}
// Record that we are looking at an expression, and return true if we
-// have already seen it.
+// have already seen it. NB: this routine used to assert if the traverse
+// mask did not include expressions/types -- this is no longer the case,
+// since it can be useful to remember specific expressions during
+// walks that only cover statements.
bool
Traverse::remember_expression(const Expression* expression)
{
- go_assert((this->traverse_mask() & traverse_types) != 0
- || (this->traverse_mask() & traverse_expressions) != 0);
if (this->expressions_seen_ == NULL)
this->expressions_seen_ = new Expressions_seen();
std::pair<Expressions_seen::iterator, bool> ins =