From bdd164b7ef5a59922e441c3d1621223105fcf267 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Sun, 20 Mar 2016 18:20:49 -0400 Subject: [PATCH] translator: PR13283 redux, optimize string comparison again With the function-overloading machinery now assuring that function calls translate to full temporaries to hold return values, we no longer need to make yet another copy just to evaluate string comparisons. --- translate.cxx | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/translate.cxx b/translate.cxx index 465291620..5daf725c7 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4875,16 +4875,17 @@ c_unparser::visit_comparison (comparison* e) if (e->right->type != pe_string) throw SEMANTIC_ERROR (_("expected string types"), e->tok); - o->line() << "({"; - o->indent(1); - - tmpvar left = gensym (pe_string); - c_assign (left, e->left, "assignment"); + // PR13283 indicated that we may need a temporary variable to + // store the operand strings, if e.g. they are both references + // into function call __retvalue's, which overlap in memory. + // ... but we now handle that inside the function call machinery, + // which always returns an allocated temporary variable. - o->newline() << "strncmp (" << left << ", "; + o->line() << "(strncmp (("; + e->left->visit (this); + o->line() << "), ("; e->right->visit (this); - o->line() << ", MAXSTRINGLEN) " << e->op << " 0;"; - o->newline(-1) << "})"; + o->line() << "), MAXSTRINGLEN) " << e->op << " 0)"; } else if (e->left->type == pe_long) { @@ -5472,6 +5473,11 @@ c_unparser::visit_functioncall (functioncall* e) // store the return value after the function arguments have been worked out // to avoid problems that may occure with nesting. tmpvar tmp_ret = gensym (e->type); + + // NB: as per PR13283, it's important we always allocate a distinct + // temporary value to receive the return value. (We can pass its + // address by reference to the function if we like.) + bool yield = false; // set if statement expression is non void for (unsigned fd = 0; fd < e->referents.size(); fd++) @@ -5548,6 +5554,7 @@ c_unparser::visit_functioncall (functioncall* e) o->newline() << "fc_end_" << fc_counter++ << ":"; } + // check for aborted return from function; this could happen from non-overloaded ones too o->newline() << "if (unlikely(c->next)) { c->last_error = \"all functions exhausted\"; goto out; }"; // return result from retvalue slot NB: this must be last, for the -- 2.43.5