From: Marc Glisse Date: Thu, 3 Oct 2013 16:13:54 +0000 (+0200) Subject: re PR c++/19476 (Missed null checking elimination with new) X-Git-Tag: releases/gcc-4.9.0~3726 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2284b03444d6845ce6402db37f4ec43f6c755f77;p=thirdparty%2Fgcc.git re PR c++/19476 (Missed null checking elimination with new) 2013-10-03 Marc Glisse 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5d2b685a9b7d..e7e28363180f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2013-10-03 Marc Glisse + + 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 * config/rs6000/rs6000-builtin.def (XSRDPIM): Use floatdf2, diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index c7a8c7872cc5..d468344c735e 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,8 @@ +2013-10-03 Marc Glisse + + PR c++/19476 + * c.opt (fcheck-new): Move to common.opt. + 2013-09-25 Marek Polacek Jakub Jelinek diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 24d1b87d11f3..e8dde935c169 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 f489f4baf75f..e25f2ab74f0b 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 c2b3d3573025..1f11fcd4d5d3 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 fc29291c01d8..03d62f51721d 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 6e84ea52cb27..6ea99fb73ffa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2013-10-03 Marc Glisse + + 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 * 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 000000000000..f0fb8d6d1f47 --- /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 + +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 000000000000..70002dbb5ea2 --- /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 + +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 000000000000..051866e13c1f --- /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 + +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 000000000000..8ae16140d649 --- /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 + +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 3464529ca856..cf0f1b1fce56 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)