Commit 2284b034 by Marc Glisse Committed by Marc Glisse

re PR c++/19476 (Missed null checking elimination with new)

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
parent 0609bdf2
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,
......
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>
......
......@@ -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
......
......@@ -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;
}
......
......@@ -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.
......
......@@ -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;
......
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
......
/* { 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" } } */
/* { 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" } } */
/* { 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" } } */
/* { 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" } } */
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment