1) It occurred to me that now that there are side-effects in
constant-expressions, we need to guard against multiple evaluation of
SAVE_EXPR.
2) We don't want to complain about flowing off the end of a function
because something in the function was non-constant.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 87438df56d20107f2f9699ab0306991a03aa7abb
Author: Jason Merrill <ja...@redhat.com>
Date: Wed Nov 26 11:13:03 2014 -0500
* constexpr.c (cxx_eval_constant_expression) [SAVE_EXPR]: Avoid
multiple evaluation.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 111ea5b..ef9ef70 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -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),
commit e1851b1d2be83cf9ee13a8a21faac3dcac52d746
Author: Jason Merrill <ja...@redhat.com>
Date: Wed Nov 26 12:00:20 2014 -0500
* constexpr.c (cxx_eval_call_expression): Don't talk about
flowing off the end if we're already non-constant.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 2678223..111ea5b 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1344,7 +1344,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
else
{
result = *ctx->values->get (slot ? slot : res);
- if (result == NULL_TREE)
+ if (result == NULL_TREE && !*non_constant_p)
{
if (!ctx->quiet)
error ("constexpr call flows off the end "