summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2016-04-19 18:50:01 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2016-04-19 18:50:01 +0000
commitcf03ba19a953659ff09d08f04eb2918495dd9283 (patch)
tree1336ed93e5a4de77dfaa2b17b0c13904ac27463e
parentd198067108c5306301ab067019aec518d089b6fe (diff)
downloadgcc-cf03ba19a953659ff09d08f04eb2918495dd9283.tar.gz
Improve constexpr handling of other loop forms.
* constexpr.c (breaks): Handle EXIT_EXPR. (cxx_eval_loop_expr): Handle COMPOUND_EXPR body. (cxx_eval_constant_expression): Handle EXIT_EXPR, improve handling of COMPOUND_EXPR. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235218 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/constexpr.c22
2 files changed, 23 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5fb16543192..a2509af865b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
2016-04-19 Jason Merrill <jason@redhat.com>
+ * constexpr.c (breaks): Handle EXIT_EXPR.
+ (cxx_eval_loop_expr): Handle COMPOUND_EXPR body.
+ (cxx_eval_constant_expression): Handle EXIT_EXPR, improve handling
+ of COMPOUND_EXPR.
+
PR c++/68206
PR c++/68530
* constexpr.c (potential_constant_expression_1): Handle LOOP_EXPR
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index d50866094d1..41f0b5c00ee 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -3241,8 +3241,9 @@ static bool
breaks (tree *jump_target)
{
return *jump_target
- && TREE_CODE (*jump_target) == LABEL_DECL
- && LABEL_DECL_BREAK (*jump_target);
+ && ((TREE_CODE (*jump_target) == LABEL_DECL
+ && LABEL_DECL_BREAK (*jump_target))
+ || TREE_CODE (*jump_target) == EXIT_EXPR);
}
static bool
@@ -3358,8 +3359,8 @@ cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t,
hash_set<tree> save_exprs;
new_ctx.save_exprs = &save_exprs;
- cxx_eval_statement_list (&new_ctx, body,
- non_constant_p, overflow_p, jump_target);
+ cxx_eval_constant_expression (&new_ctx, body, /*lval*/false,
+ non_constant_p, overflow_p, jump_target);
/* Forget saved values of SAVE_EXPRs. */
for (hash_set<tree>::iterator iter = save_exprs.begin();
@@ -3750,6 +3751,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
cxx_eval_constant_expression (ctx, op0,
true, non_constant_p, overflow_p,
jump_target);
+ if (*non_constant_p)
+ return t;
op1 = TREE_OPERAND (t, 1);
r = cxx_eval_constant_expression (ctx, op1,
lval, non_constant_p, overflow_p,
@@ -4015,6 +4018,17 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
}
break;
+ case EXIT_EXPR:
+ {
+ tree cond = TREE_OPERAND (t, 0);
+ cond = cxx_eval_constant_expression (ctx, cond, /*lval*/false,
+ non_constant_p, overflow_p);
+ VERIFY_CONSTANT (cond);
+ if (integer_nonzerop (cond))
+ *jump_target = t;
+ }
+ break;
+
case GOTO_EXPR:
*jump_target = TREE_OPERAND (t, 0);
gcc_assert (breaks (jump_target) || continues (jump_target));