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 e961169fea33a8551f6ef199fa9a7e18546dc1f3..32092c418a15e10de09fef03e9b09e5525cef2f3 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 111ea5b1a0101dbf56ad7c6d71d6742eb4d3e93d..ef9ef70d6e0b303e0196a20ebbb4c3eda311f3eb 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),