On Mon, Sep 9, 2013 at 4:06 AM, Richard Biener <richard.guent...@gmail.com> wrote: > 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)?
We should distinguish between front-end notion of null pointer, and backend notion of address zero. The language, and therefore the front-end, does not allow an object to have 'this' value to be a null pointer, nor does is allow 'operator new' to return null pointer. Consequently, if we have a target (which ones?) where zero is a valid address for an object, that target should take precaution to satisfy the requirement of the language. -- Gaby > > 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)); >> >>