constexpr.c (cxx_eval_constant_expression): Avoid multiple evaluation.
authorJason Merrill <jason@redhat.com>
Wed, 26 Nov 2014 18:20:18 +0000 (13:20 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 26 Nov 2014 18:20:18 +0000 (13:20 -0500)
* constexpr.c (cxx_eval_constant_expression) [SAVE_EXPR]: Avoid
multiple evaluation.

From-SVN: r218093

gcc/cp/ChangeLog
gcc/cp/constexpr.c

index e961169..32092c4 100644 (file)
@@ -1,5 +1,8 @@
 2014-11-26  Jason Merrill  <jason@redhat.com>
 
+       * constexpr.c (cxx_eval_constant_expression) [SAVE_EXPR]: Avoid
+       multiple evaluation.
+
        * constexpr.c (cxx_eval_call_expression): Don't talk about
        flowing off the end if we're already non-constant.
 
index 111ea5b..ef9ef70 100644 (file)
@@ -2974,11 +2974,22 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
       *jump_target = t;
       break;
 
+    case SAVE_EXPR:
+      /* Avoid evaluating a SAVE_EXPR more than once.  */
+      if (tree *p = ctx->values->get (t))
+       r = *p;
+      else
+       {
+         r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), addr,
+                                           non_constant_p, overflow_p);
+         ctx->values->put (t, r);
+       }
+      break;
+
     case NON_LVALUE_EXPR:
     case TRY_CATCH_EXPR:
     case CLEANUP_POINT_EXPR:
     case MUST_NOT_THROW_EXPR:
-    case SAVE_EXPR:
     case EXPR_STMT:
     case EH_SPEC_BLOCK:
       r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),