re PR c++/84449 (ICE with constexpr and deleted destructor)
authorJakub Jelinek <jakub@redhat.com>
Tue, 20 Feb 2018 08:21:36 +0000 (09:21 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 20 Feb 2018 08:21:36 +0000 (09:21 +0100)
PR c++/84449
* tree.c (bot_manip): If build_cplus_new or break_out_target_exprs
returns error_mark_node, return it immediately.
(break_out_target_exprs): If cp_walk_tree with bot_manip returns
error_mark_node, return error_mark_node.

* g++.dg/cpp0x/constexpr-84449.C: New test.

From-SVN: r257839

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

index 726c0951499bac8ae3eac6ae0a6333bc50b7bd3b..8a786bb4c0692de324bfccc713c619766a8e0d31 100644 (file)
@@ -1,5 +1,11 @@
 2018-02-20  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/84449
+       * tree.c (bot_manip): If build_cplus_new or break_out_target_exprs
+       returns error_mark_node, return it immediately.
+       (break_out_target_exprs): If cp_walk_tree with bot_manip returns
+       error_mark_node, return error_mark_node.
+
        PR c++/84455
        * pt.c (tsubst_lambda_expr): If not nested, increment temporarily
        function_depth to avoid GC during finish_lambda_function.
index a53bddf2ef009fe4d66e7483967a68335377839e..39c1ef28b2d04a5f5dea72d63d550ea26626834c 100644 (file)
@@ -2896,6 +2896,8 @@ bot_manip (tree* tp, int* walk_subtrees, void* data)
        {
          u = build_cplus_new (TREE_TYPE (t), TREE_OPERAND (t, 1),
                               tf_warning_or_error);
+         if (u == error_mark_node)
+           return u;
          if (AGGR_INIT_ZERO_FIRST (TREE_OPERAND (t, 1)))
            AGGR_INIT_ZERO_FIRST (TREE_OPERAND (u, 1)) = true;
        }
@@ -2913,6 +2915,8 @@ bot_manip (tree* tp, int* walk_subtrees, void* data)
                         (splay_tree_value) TREE_OPERAND (u, 0));
 
       TREE_OPERAND (u, 1) = break_out_target_exprs (TREE_OPERAND (u, 1));
+      if (TREE_OPERAND (u, 1) == error_mark_node)
+       return error_mark_node;
 
       /* Replace the old expression with the new version.  */
       *tp = u;
@@ -3025,7 +3029,8 @@ break_out_target_exprs (tree t)
     target_remap = splay_tree_new (splay_tree_compare_pointers,
                                   /*splay_tree_delete_key_fn=*/NULL,
                                   /*splay_tree_delete_value_fn=*/NULL);
-  cp_walk_tree (&t, bot_manip, target_remap, NULL);
+  if (cp_walk_tree (&t, bot_manip, target_remap, NULL) == error_mark_node)
+    t = error_mark_node;
   cp_walk_tree (&t, bot_replace, target_remap, NULL);
 
   if (!--target_remap_count)
index 9c1391e612018ad85fe5678618b7073c113d6524..fd21d3b8a42bf390d77bf009e6a13f4e85025862 100644 (file)
@@ -1,5 +1,8 @@
 2018-02-20  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/84449
+       * g++.dg/cpp0x/constexpr-84449.C: New test.
+
        PR c++/84455
        * g++.dg/cpp0x/lambda/lambda-ice26.C: New test.
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-84449.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-84449.C
new file mode 100644 (file)
index 0000000..f187c42
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/84449
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+  constexpr A (int) {}
+  ~A () = delete;
+};
+
+struct B
+{
+  A a;
+  constexpr B () : a (0) {}    // { dg-error "use of deleted function" }
+};