re PR c++/66001 (ICE when NSDMI in a literal class uses a destructor)
authorJason Merrill <jason@redhat.com>
Thu, 18 Jun 2015 14:55:23 +0000 (10:55 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 18 Jun 2015 14:55:23 +0000 (10:55 -0400)
PR c++/66001
* constexpr.c (cxx_eval_constant_expression): Handle TRY_BLOCK and
TRY_FINALLY_EXPR.
(potential_constant_expression_1): Likewise.

From-SVN: r224620

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

index 153b3c4cd74ab2a1e784049b205e0ec9406b2af5..eb8d97ab1e8a400b485a9990fed21bcd66ec0b60 100644 (file)
@@ -1,3 +1,10 @@
+2015-06-17  Jason Merrill  <jason@redhat.com>
+
+       PR c++/66001
+       * constexpr.c (cxx_eval_constant_expression): Handle TRY_BLOCK and
+       TRY_FINALLY_EXPR.
+       (potential_constant_expression_1): Likewise.
+
 2015-06-17  Jason Merrill  <jason@redhat.com>
 
        PR c++/66515
index a52c96ff6b4169969fe0c19f9ef1247376ef105e..56885883d72aa090f45ceed274fc29bfd55e7dfa 100644 (file)
@@ -3182,6 +3182,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 
     case NON_LVALUE_EXPR:
     case TRY_CATCH_EXPR:
+    case TRY_BLOCK:
     case CLEANUP_POINT_EXPR:
     case MUST_NOT_THROW_EXPR:
     case EXPR_STMT:
@@ -3192,6 +3193,17 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
                                        jump_target);
       break;
 
+    case TRY_FINALLY_EXPR:
+      r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
+                                       non_constant_p, overflow_p,
+                                       jump_target);
+      if (!*non_constant_p)
+       /* Also evaluate the cleanup.  */
+       cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), true,
+                                     non_constant_p, overflow_p,
+                                     jump_target);
+      break;
+
       /* These differ from cxx_eval_unary_expression in that this doesn't
         check for a constant operand or result; an address can be
         constant without its operand being, and vice versa.  */
@@ -4266,6 +4278,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
     case CLEANUP_POINT_EXPR:
     case MUST_NOT_THROW_EXPR:
     case TRY_CATCH_EXPR:
+    case TRY_BLOCK:
     case EH_SPEC_BLOCK:
     case EXPR_STMT:
     case PAREN_EXPR:
@@ -4275,6 +4288,10 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
     case RETURN_EXPR:
       return RECUR (TREE_OPERAND (t, 0), want_rval);
 
+    case TRY_FINALLY_EXPR:
+      return (RECUR (TREE_OPERAND (t, 0), want_rval)
+             && RECUR (TREE_OPERAND (t, 1), any));
+
     case SCOPE_REF:
       return RECUR (TREE_OPERAND (t, 1), want_rval);
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi12.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi12.C
new file mode 100644 (file)
index 0000000..11618a4
--- /dev/null
@@ -0,0 +1,16 @@
+// PR c++/66001
+// { dg-do compile { target c++11 } }
+
+#include <initializer_list>
+
+struct dt
+    { dt() {} ~ dt() {} };
+
+struct x {
+    std::initializer_list< dt > f = { {} };
+} cx;
+
+struct x2 {
+    struct dt { ~ dt() {} }
+        const & m = {};
+} cx2;