On Sat, Sep 7, 2013 at 11:00 PM, Marc Glisse <marc.gli...@inria.fr> wrote: > On Sat, 7 Sep 2013, Mike Stump wrote: > >> On Sep 7, 2013, at 12:27 PM, Marc Glisse <marc.gli...@inria.fr> wrote: >>> >>> Now flag_check_new should probably disable this optimization… >> >> >> Yes, this why my point. > > > Ok, here it is (again, no proper testing until bootstrap is fixed)
I wonder what happens on targets where 0 is a valid address of an object (stated by !flag_delete_null_pointer_checks)? Richard. > > 2013-09-07 Marc Glisse <marc.gli...@inria.fr> > > PR c++/19476 > gcc/ > * 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. > > -- > Marc Glisse > Index: testsuite/g++.dg/tree-ssa/pr19476-1.C > =================================================================== > --- testsuite/g++.dg/tree-ssa/pr19476-1.C (revision 0) > +++ testsuite/g++.dg/tree-ssa/pr19476-1.C (revision 0) > @@ -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" } } */ > > Property changes on: testsuite/g++.dg/tree-ssa/pr19476-1.C > ___________________________________________________________________ > Added: svn:keywords > + Author Date Id Revision URL > Added: svn:eol-style > + native > > Index: testsuite/g++.dg/tree-ssa/pr19476-2.C > =================================================================== > --- testsuite/g++.dg/tree-ssa/pr19476-2.C (revision 0) > +++ testsuite/g++.dg/tree-ssa/pr19476-2.C (revision 0) > @@ -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" } } */ > > Property changes on: testsuite/g++.dg/tree-ssa/pr19476-2.C > ___________________________________________________________________ > Added: svn:keywords > + Author Date Id Revision URL > Added: svn:eol-style > + native > > Index: testsuite/g++.dg/tree-ssa/pr19476-3.C > =================================================================== > --- testsuite/g++.dg/tree-ssa/pr19476-3.C (revision 0) > +++ testsuite/g++.dg/tree-ssa/pr19476-3.C (revision 0) > @@ -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" } } */ > > Property changes on: testsuite/g++.dg/tree-ssa/pr19476-3.C > ___________________________________________________________________ > Added: svn:keywords > + Author Date Id Revision URL > Added: svn:eol-style > + native > > Index: fold-const.c > =================================================================== > --- fold-const.c (revision 202351) > +++ fold-const.c (working copy) > @@ -16171,21 +16171,31 @@ tree_expr_nonzero_warnv_p (tree t, bool > case MODIFY_EXPR: > case BIND_EXPR: > return tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1), > strict_overflow_p); > > case SAVE_EXPR: > return tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0), > strict_overflow_p); > > case CALL_EXPR: > - return alloca_call_p (t); > + { > + tree fn = CALL_EXPR_FN (t); > + if (TREE_CODE (fn) != ADDR_EXPR) return false; > + tree fndecl = TREE_OPERAND (fn, 0); > + if (TREE_CODE (fndecl) != FUNCTION_DECL) return false; > + if (!flag_check_new > + && DECL_IS_OPERATOR_NEW (fndecl) > + && !TREE_NOTHROW (fndecl)) > + return true; > + return alloca_call_p (t); > + } > > default: > break; > } > return false; > } > > /* Return true when T is an address and is known to be nonzero. > Handle warnings about undefined signed overflow. */ > > Index: tree-vrp.c > =================================================================== > --- tree-vrp.c (revision 202351) > +++ tree-vrp.c (working copy) > @@ -1047,21 +1047,29 @@ gimple_assign_nonzero_warnv_p (gimple st > *STRICT_OVERFLOW_P.*/ > > static bool > gimple_stmt_nonzero_warnv_p (gimple stmt, bool *strict_overflow_p) > { > switch (gimple_code (stmt)) > { > 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_check_new > + && DECL_IS_OPERATOR_NEW (fndecl) > + && !TREE_NOTHROW (fndecl)) > + return true; > + return gimple_alloca_call_p (stmt); > + } > default: > gcc_unreachable (); > } > } > > /* Like tree_expr_nonzero_warnv_p, but this function uses value ranges > obtained so far. */ > > static bool > vrp_stmt_computes_nonzero (gimple stmt, bool *strict_overflow_p) > @@ -6486,21 +6494,22 @@ stmt_interesting_for_vrp (gimple stmt) > tree lhs = gimple_get_lhs (stmt); > > /* In general, assignments with virtual operands are not useful > for deriving ranges, with the obvious exception of calls to > builtin functions. */ > if (lhs && TREE_CODE (lhs) == SSA_NAME > && (INTEGRAL_TYPE_P (TREE_TYPE (lhs)) > || 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; > } > else if (gimple_code (stmt) == GIMPLE_COND > || gimple_code (stmt) == GIMPLE_SWITCH) > return true; > > return false; > } > > @@ -7407,30 +7416,21 @@ vrp_visit_stmt (gimple stmt, edge *taken > if (dump_file && (dump_flags & TDF_DETAILS)) > { > fprintf (dump_file, "\nVisiting statement:\n"); > print_gimple_stmt (dump_file, stmt, 0, dump_flags); > fprintf (dump_file, "\n"); > } > > 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) > return vrp_visit_switch_stmt (stmt, taken_edge_p); > > /* All other statements produce nothing of interest for VRP, so mark > their outputs varying and prevent further simulation. */ > FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF) > set_value_range_to_varying (get_value_range (def)); > >