Handle new operators with no arguments in DCE.
authorMartin Liska <mliska@suse.cz>
Mon, 5 Aug 2019 12:53:01 +0000 (14:53 +0200)
committerMartin Liska <marxin@gcc.gnu.org>
Mon, 5 Aug 2019 12:53:01 +0000 (12:53 +0000)
2019-08-05  Martin Liska  <mliska@suse.cz>

PR c++/91334
* tree-ssa-dce.c (propagate_necessity): Handle new operators
with not arguments.
(eliminate_unnecessary_stmts): Likewise.
2019-08-05  Martin Liska  <mliska@suse.cz>

PR c++/91334
* g++.dg/torture/pr91334.C: New test.

From-SVN: r274115

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr91334.C [new file with mode: 0644]
gcc/tree-ssa-dce.c

index c118e4d..892f7aa 100644 (file)
@@ -1,3 +1,10 @@
+2019-08-05  Martin Liska  <mliska@suse.cz>
+
+       PR c++/91334
+       * tree-ssa-dce.c (propagate_necessity): Handle new operators
+       with not arguments.
+       (eliminate_unnecessary_stmts): Likewise.
+
 2019-08-05  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/91169
index 5dc9d11..cff940e 100644 (file)
@@ -1,3 +1,8 @@
+2019-08-05  Martin Liska  <mliska@suse.cz>
+
+       PR c++/91334
+       * g++.dg/torture/pr91334.C: New test.
+
 2019-08-05  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/91169
diff --git a/gcc/testsuite/g++.dg/torture/pr91334.C b/gcc/testsuite/g++.dg/torture/pr91334.C
new file mode 100644 (file)
index 0000000..ba79d71
--- /dev/null
@@ -0,0 +1,14 @@
+/* PR c++/91334.  */
+/* { dg-do compile } */
+
+#include <new>
+#include <stdlib.h>
+
+struct A {
+  A() { throw 0; }
+  void* operator new(size_t size, double = 0.0) { return ::operator new(size);}
+  void operator delete(void* p, double) { exit(0); }
+  void operator delete(void* p) { abort(); }
+};
+
+int main() { try { new A; } catch(...) {} }
index 80d5f5c..afb7bd9 100644 (file)
@@ -810,6 +810,11 @@ propagate_necessity (bool aggressive)
          if (is_delete_operator
              || gimple_call_builtin_p (stmt, BUILT_IN_FREE))
            {
+             /* It can happen that a user delete operator has the pointer
+                argument optimized out already.  */
+             if (gimple_call_num_args (stmt) == 0)
+               continue;
+
              tree ptr = gimple_call_arg (stmt, 0);
              gimple *def_stmt;
              tree def_callee;
@@ -1323,13 +1328,18 @@ eliminate_unnecessary_stmts (void)
                  || (is_gimple_call (stmt)
                      && gimple_call_operator_delete_p (as_a <gcall *> (stmt)))))
            {
-             tree ptr = gimple_call_arg (stmt, 0);
-             if (TREE_CODE (ptr) == SSA_NAME)
+             /* It can happen that a user delete operator has the pointer
+                argument optimized out already.  */
+             if (gimple_call_num_args (stmt) > 0)
                {
-                 gimple *def_stmt = SSA_NAME_DEF_STMT (ptr);
-                 if (!gimple_nop_p (def_stmt)
-                     && !gimple_plf (def_stmt, STMT_NECESSARY))
-                   gimple_set_plf (stmt, STMT_NECESSARY, false);
+                 tree ptr = gimple_call_arg (stmt, 0);
+                 if (TREE_CODE (ptr) == SSA_NAME)
+                   {
+                     gimple *def_stmt = SSA_NAME_DEF_STMT (ptr);
+                     if (!gimple_nop_p (def_stmt)
+                         && !gimple_plf (def_stmt, STMT_NECESSARY))
+                       gimple_set_plf (stmt, STMT_NECESSARY, false);
+                   }
                }
            }