aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/c-family/ChangeLog5
-rw-r--r--gcc/c-family/c.opt4
-rw-r--r--gcc/calls.c7
-rw-r--r--gcc/common.opt4
-rw-r--r--gcc/fold-const.c10
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr19476-1.C15
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr19476-2.C17
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr19476-3.C11
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr19476-4.C11
-rw-r--r--gcc/tree-vrp.c24
12 files changed, 105 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5d2b685..e7e2836 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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,
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index c7a8c787..d468344 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -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>
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 24d1b87..e8dde93 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -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
diff --git a/gcc/calls.c b/gcc/calls.c
index f489f4b..e25f2ab 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -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;
}
diff --git a/gcc/common.opt b/gcc/common.opt
index c2b3d35..1f11fcd 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -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.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index fc29291..03d62f5 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6e84ea5..6ea99fb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..f0fb8d6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr19476-1.C
@@ -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
index 0000000..70002db
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr19476-2.C
@@ -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
index 0000000..051866e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr19476-3.C
@@ -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
index 0000000..8ae1614
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr19476-4.C
@@ -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" } } */
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 3464529..cf0f1b1 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -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)