Improve constexpr handling of other loop forms.
authorJason Merrill <jason@redhat.com>
Tue, 19 Apr 2016 18:50:01 +0000 (14:50 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 19 Apr 2016 18:50:01 +0000 (14:50 -0400)
* 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.

From-SVN: r235218

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

index 5fb1654319299919233d5c24e370b6599235ee81..a2509af865b9cbf6233b4c25f5c2059d5950c91b 100644 (file)
@@ -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
index d50866094d1032a09b29a39f752552022682ba6a..41f0b5c00eece9fbe0e8bd0dc87665625b8332be 100644 (file)
@@ -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));