// 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)
}
// 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 =