]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/19476 (Missed null checking elimination with new)
authorMarc Glisse <marc.glisse@inria.fr>
Thu, 3 Oct 2013 16:13:54 +0000 (18:13 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Thu, 3 Oct 2013 16:13:54 +0000 (16:13 +0000)
2013-10-03  Marc Glisse  <marc.glisse@inria.fr>

PR c++/19476
gcc/c-family/
* c.opt (fcheck-new): Move to common.opt.

gcc/
* common.opt (fcheck-new): Moved from c.opt. Make it 'Common'.
* calls.c (alloca_call_p): Use get_callee_fndecl.
* fold-const.c (tree_expr_nonzero_warnv_p): Handle operator new.
* tree-vrp.c (gimple_stmt_nonzero_warnv_p, stmt_interesting_for_vrp):
Likewise.
(vrp_visit_stmt): Remove duplicated code.

gcc/testsuite/
* g++.dg/tree-ssa/pr19476-1.C: New file.
* g++.dg/tree-ssa/pr19476-2.C: Likewise.
* g++.dg/tree-ssa/pr19476-3.C: Likewise.
* g++.dg/tree-ssa/pr19476-4.C: Likewise.

From-SVN: r203163

12 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c.opt
gcc/calls.c
gcc/common.opt
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/tree-ssa/pr19476-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tree-ssa/pr19476-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tree-ssa/pr19476-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tree-ssa/pr19476-4.C [new file with mode: 0644]
gcc/tree-vrp.c

index 5d2b685a9b7dde5fddb77f812fd584ae8b19240e..e7e28363180f32e1ef50e157a08006d8960c92f3 100644 (file)
@@ -1,3 +1,13 @@
+2013-10-03  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR c++/19476
+       * common.opt (fcheck-new): Moved from c.opt. Make it 'Common'.
+       * calls.c (alloca_call_p): Use get_callee_fndecl.
+       * fold-const.c (tree_expr_nonzero_warnv_p): Handle operator new.
+       * tree-vrp.c (gimple_stmt_nonzero_warnv_p, stmt_interesting_for_vrp):
+       Likewise.
+       (vrp_visit_stmt): Remove duplicated code.
+
 2013-10-03  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        * config/rs6000/rs6000-builtin.def (XSRDPIM): Use floatdf2,
index c7a8c7872cc5e5870b9fd6e2e8f653e0e2fd6528..d468344c735e68859fcab03834607b6a9fc079c2 100644 (file)
@@ -1,3 +1,8 @@
+2013-10-03  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR c++/19476
+       * c.opt (fcheck-new): Move to common.opt.
+
 2013-09-25  Marek Polacek  <polacek@redhat.com>
            Jakub Jelinek  <jakub@redhat.com>
 
index 24d1b87d11f33ac9adc98a7b54d77da64b5a6442..e8dde935c169471b180d74a726ef70e1f92be1ab 100644 (file)
@@ -855,10 +855,6 @@ fcilkplus
 C ObjC C++ ObjC++ LTO Report Var(flag_enable_cilkplus) Init(0)
 Enable Cilk Plus
 
-fcheck-new
-C++ ObjC++ Var(flag_check_new)
-Check the return value of new
-
 fcond-mismatch
 C ObjC C++ ObjC++
 Allow the arguments of the '?' operator to have different types
index f489f4baf75f71904974610ff0b39d2a007b7b75..e25f2ab74f0b175dcfb2dbef4cd2fe5c2eb498cc 100644 (file)
@@ -635,11 +635,10 @@ gimple_alloca_call_p (const_gimple stmt)
 bool
 alloca_call_p (const_tree exp)
 {
+  tree fndecl;
   if (TREE_CODE (exp) == CALL_EXPR
-      && TREE_CODE (CALL_EXPR_FN (exp)) == ADDR_EXPR
-      && (TREE_CODE (TREE_OPERAND (CALL_EXPR_FN (exp), 0)) == FUNCTION_DECL)
-      && (special_function_p (TREE_OPERAND (CALL_EXPR_FN (exp), 0), 0)
-         & ECF_MAY_BE_ALLOCA))
+      && (fndecl = get_callee_fndecl (exp))
+      && (special_function_p (fndecl, 0) & ECF_MAY_BE_ALLOCA))
     return true;
   return false;
 }
index c2b3d35730258c4b8635dc2969cd75c0bfb4b533..1f11fcd4d5d3cbd1e3f66771a6b5f02ea9cc0c26 100644 (file)
@@ -913,6 +913,10 @@ fcheck-data-deps
 Common Report Var(flag_check_data_deps)
 Compare the results of several data dependence analyzers.
 
+fcheck-new
+Common Var(flag_check_new)
+Check the return value of new in C++
+
 fcombine-stack-adjustments
 Common Report Var(flag_combine_stack_adjustments) Optimization
 Looks for opportunities to reduce stack adjustments and stack references.
index fc29291c01d84aea7a5ee31e06f6c3520f2354d3..03d62f51721d8220bb72315265b8d6149aa56ade 100644 (file)
@@ -16222,7 +16222,15 @@ tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
                                        strict_overflow_p);
 
     case CALL_EXPR:
-      return alloca_call_p (t);
+      {
+       tree fndecl = get_callee_fndecl (t);
+       if (!fndecl) return false;
+       if (flag_delete_null_pointer_checks && !flag_check_new
+           && DECL_IS_OPERATOR_NEW (fndecl)
+           && !TREE_NOTHROW (fndecl))
+         return true;
+       return alloca_call_p (t);
+      }
 
     default:
       break;
index 6e84ea52cb27ec0a3b0f065ef7530cf37c0e9d4f..6ea99fb73ffaef7e25070c9ecc1375f3fbc7ec47 100644 (file)
@@ -1,3 +1,11 @@
+2013-10-03  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR c++/19476
+       * g++.dg/tree-ssa/pr19476-1.C: New file.
+       * g++.dg/tree-ssa/pr19476-2.C: Likewise.
+       * g++.dg/tree-ssa/pr19476-3.C: Likewise.
+       * g++.dg/tree-ssa/pr19476-4.C: Likewise.
+
 2013-10-03  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        * gcc.target/powerpc/p8vector-fp.c: New test for floating point
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr19476-1.C b/gcc/testsuite/g++.dg/tree-ssa/pr19476-1.C
new file mode 100644 (file)
index 0000000..f0fb8d6
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-ccp1" } */
+
+#include <new>
+
+int f(){
+  return 33 + (0 == new(std::nothrow) int);
+}
+int g(){
+  return 42 + (0 == new int[50]);
+}
+
+/* { dg-final { scan-tree-dump     "return 42" "ccp1" } } */
+/* { dg-final { scan-tree-dump-not "return 33" "ccp1" } } */
+/* { dg-final { cleanup-tree-dump "ccp1" } } */
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr19476-2.C b/gcc/testsuite/g++.dg/tree-ssa/pr19476-2.C
new file mode 100644 (file)
index 0000000..70002db
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+#include <new>
+
+int f(){
+  int *p = new(std::nothrow) int;
+  return 33 + (0 == p);
+}
+int g(){
+  int *p = new int[50];
+  return 42 + (0 == p);
+}
+
+/* { dg-final { scan-tree-dump     "return 42" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "return 33" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr19476-3.C b/gcc/testsuite/g++.dg/tree-ssa/pr19476-3.C
new file mode 100644 (file)
index 0000000..051866e
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fcheck-new -fdump-tree-optimized" } */
+
+#include <new>
+
+int g(){
+  return 42 + (0 == new int);
+}
+
+/* { dg-final { scan-tree-dump-not "return 42" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr19476-4.C b/gcc/testsuite/g++.dg/tree-ssa/pr19476-4.C
new file mode 100644 (file)
index 0000000..8ae1614
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fno-delete-null-pointer-checks -fdump-tree-optimized" } */
+
+#include <new>
+
+int g(){
+  return 42 + (0 == new int);
+}
+
+/* { dg-final { scan-tree-dump-not "return 42" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
index 3464529ca8569476523c611220669c1ba1ec548c..cf0f1b1fce56e8701436bdbcbb502c1225dcb086 100644 (file)
@@ -1051,7 +1051,15 @@ gimple_stmt_nonzero_warnv_p (gimple stmt, bool *strict_overflow_p)
     case GIMPLE_ASSIGN:
       return gimple_assign_nonzero_warnv_p (stmt, strict_overflow_p);
     case GIMPLE_CALL:
-      return gimple_alloca_call_p (stmt);
+      {
+       tree fndecl = gimple_call_fndecl (stmt);
+       if (!fndecl) return false;
+       if (flag_delete_null_pointer_checks && !flag_check_new
+           && DECL_IS_OPERATOR_NEW (fndecl)
+           && !TREE_NOTHROW (fndecl))
+         return true;
+       return gimple_alloca_call_p (stmt);
+      }
     default:
       gcc_unreachable ();
     }
@@ -6490,7 +6498,8 @@ stmt_interesting_for_vrp (gimple stmt)
              || POINTER_TYPE_P (TREE_TYPE (lhs)))
          && ((is_gimple_call (stmt)
               && gimple_call_fndecl (stmt) != NULL_TREE
-              && DECL_BUILT_IN (gimple_call_fndecl (stmt)))
+              && (DECL_BUILT_IN (gimple_call_fndecl (stmt))
+                  || DECL_IS_OPERATOR_NEW (gimple_call_fndecl (stmt))))
              || !gimple_vuse (stmt)))
        return true;
     }
@@ -7411,16 +7420,7 @@ vrp_visit_stmt (gimple stmt, edge *taken_edge_p, tree *output_p)
   if (!stmt_interesting_for_vrp (stmt))
     gcc_assert (stmt_ends_bb_p (stmt));
   else if (is_gimple_assign (stmt) || is_gimple_call (stmt))
-    {
-      /* In general, assignments with virtual operands are not useful
-        for deriving ranges, with the obvious exception of calls to
-        builtin functions.  */
-      if ((is_gimple_call (stmt)
-          && gimple_call_fndecl (stmt) != NULL_TREE
-          && DECL_BUILT_IN (gimple_call_fndecl (stmt)))
-         || !gimple_vuse (stmt))
-       return vrp_visit_assignment_or_call (stmt, output_p);
-    }
+    return vrp_visit_assignment_or_call (stmt, output_p);
   else if (gimple_code (stmt) == GIMPLE_COND)
     return vrp_visit_cond_stmt (stmt, taken_edge_p);
   else if (gimple_code (stmt) == GIMPLE_SWITCH)