operator new returns nonzero

Gabriel Dos Reis gdr@integrable-solutions.net
Mon Sep 9 12:49:00 GMT 2013


On Mon, Sep 9, 2013 at 4:06 AM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Sat, Sep 7, 2013 at 11:00 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
>> On Sat, 7 Sep 2013, Mike Stump wrote:
>>
>>> On Sep 7, 2013, at 12:27 PM, Marc Glisse <marc.glisse@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.glisse@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));
>>
>>



More information about the Gcc-patches mailing list