diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-04-19 18:50:01 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-04-19 18:50:01 +0000 |
commit | cf03ba19a953659ff09d08f04eb2918495dd9283 (patch) | |
tree | 1336ed93e5a4de77dfaa2b17b0c13904ac27463e | |
parent | d198067108c5306301ab067019aec518d089b6fe (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 22 |
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)); |