constexpr.c (cxx_eval_statement_list): Handle statement-expressions.
authorJason Merrill <jason@redhat.com>
Wed, 19 Nov 2014 03:03:39 +0000 (22:03 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 19 Nov 2014 03:03:39 +0000 (22:03 -0500)
* constexpr.c (cxx_eval_statement_list): Handle statement-expressions.
(potential_constant_expression_1): Handle STMT_EXPR.

From-SVN: r217748

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/g++.dg/cpp0x/constexpr-stmtexpr2.C [new file with mode: 0644]

index e508c5ce2fb289ec421e8d9f823dfe1a1b0a570d..32f2c6f330083eabb7c6ae57eaf6f729a2e865c8 100644 (file)
@@ -1,5 +1,8 @@
 2014-11-18  Jason Merrill  <jason@redhat.com>
 
+       * constexpr.c (cxx_eval_statement_list): Handle statement-expressions.
+       (potential_constant_expression_1): Handle STMT_EXPR.
+
        * constexpr.c (cxx_eval_constant_expression): Give jump_target a
        default argument.
        (lots): Omit NULL jump_target arguments.
index 4669586ca21e50ca5b1e971597d82d8e89c20e18..1b330a048dfd903baafaf52a96a3cb05d302c1ea 100644 (file)
@@ -2685,6 +2685,14 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
 {
   tree_stmt_iterator i;
   tree_stmt_iterator default_label = tree_stmt_iterator();
+  tree local_target;
+  /* In a statement-expression we want to return the last value.  */
+  tree r = NULL_TREE;
+  if (!jump_target)
+    {
+      local_target = NULL_TREE;
+      jump_target = &local_target;
+    }
   for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
     {
     reenter:
@@ -2699,10 +2707,9 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
          else
            continue;
        }
-      cxx_eval_constant_expression (ctx, stmt,
-                                   false,
-                                   non_constant_p, overflow_p,
-                                   jump_target);
+      r = cxx_eval_constant_expression (ctx, stmt, false,
+                                       non_constant_p, overflow_p,
+                                       jump_target);
       if (*non_constant_p)
        break;
       if (returns (jump_target) || breaks (jump_target))
@@ -2714,7 +2721,7 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
       *jump_target = NULL_TREE;
       goto reenter;
     }
-  return NULL_TREE;
+  return r;
 }
 
 /* Evaluate a LOOP_EXPR for side-effects.  Handles break and return
@@ -3885,6 +3892,9 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
        return false;
       return true;
 
+    case STMT_EXPR:
+      return potential_constant_expression_1 (STMT_EXPR_STMT (t), rval, flags);
+
     case LAMBDA_EXPR:
     case DYNAMIC_CAST_EXPR:
     case PSEUDO_DTOR_EXPR:
@@ -3900,7 +3910,6 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
       /* GCC internal stuff.  */
     case VA_ARG_EXPR:
     case OBJ_TYPE_REF:
-    case STMT_EXPR:
     case TRANSACTION_EXPR:
     case ASM_EXPR:
     fail:
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-stmtexpr2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-stmtexpr2.C
new file mode 100644 (file)
index 0000000..34ca9fa
--- /dev/null
@@ -0,0 +1,12 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+#define SA(X) static_assert((X),#X)
+
+template <class T>
+constexpr T f (T t)
+{
+  return ({ t+1; });
+}
+
+SA(f(42) == 43);