public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/63459] New: operator new and returns_nonnull
@ 2014-10-04 19:24 hubicka at gcc dot gnu.org
  2014-10-04 20:27 ` [Bug c++/63459] " glisse at gcc dot gnu.org
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: hubicka at gcc dot gnu.org @ 2014-10-04 19:24 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63459

            Bug ID: 63459
           Summary: operator new and returns_nonnull
           Product: gcc
           Version: 5.0
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: hubicka at gcc dot gnu.org

compinling:

struct A {
   virtual int foo(){return 1;}
};
struct B {
   virtual int bar(){return 4;}
};
struct C:B,A {
   virtual int foo(){return 2;}
};
static void
test (struct A *a)
{
  if (a->foo() != 2)
   __builtin_abort ();
}
int
m()
{
  struct A *a = new C;
  test (a);
  return 0;
}

Leads to:
int m() ()
{
  struct A * a;
  void * _4;
  struct A * iftmp.0_6;

  <bb 2>:
  _4 = operator new (16);
  C::C (_4);
  if (_4 != 0B)
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  iftmp.0_6 = &MEM[(struct C *)_4].D.2251;

  <bb 4>:
  # a_1 = PHI <iftmp.0_6(3), 0B(2)>
  test (a_1);
  return 0;

}

in release_ssa dump.  It would be nice to use the fact that the default
operator new throw exception instead of returning NULL in out of memory case.

Can optimizer make assumption that THIS parameter to a method call is always
not NULL?


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/63459] operator new and returns_nonnull
  2014-10-04 19:24 [Bug c++/63459] New: operator new and returns_nonnull hubicka at gcc dot gnu.org
@ 2014-10-04 20:27 ` glisse at gcc dot gnu.org
  2014-10-04 20:54 ` hubicka at gcc dot gnu.org
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: glisse at gcc dot gnu.org @ 2014-10-04 20:27 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63459

--- Comment #1 from Marc Glisse <glisse at gcc dot gnu.org> ---
VRP already optimizes this, doesn't it?

Adding an implicit __attribute__((nonnull(1))) to all C++ member functions
might be good, but it also sounds a bit scary to me...


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/63459] operator new and returns_nonnull
  2014-10-04 19:24 [Bug c++/63459] New: operator new and returns_nonnull hubicka at gcc dot gnu.org
  2014-10-04 20:27 ` [Bug c++/63459] " glisse at gcc dot gnu.org
@ 2014-10-04 20:54 ` hubicka at gcc dot gnu.org
  2014-10-04 21:12 ` glisse at gcc dot gnu.org
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: hubicka at gcc dot gnu.org @ 2014-10-04 20:54 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63459

Jan Hubicka <hubicka at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2014-10-04
     Ever confirmed|0                           |1

--- Comment #2 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
Hmm, indeed:
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:
      {
        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;
        if (flag_delete_null_pointer_checks &&
            lookup_attribute ("returns_nonnull",
                              TYPE_ATTRIBUTES (gimple_call_fntype (stmt))))
          return true;
        return gimple_alloca_call_p (stmt);
      }
    default:
      gcc_unreachable ();
    }
}
I wonder if we can fold this earlier, for instance FRE1 has all info to do the
job, too.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/63459] operator new and returns_nonnull
  2014-10-04 19:24 [Bug c++/63459] New: operator new and returns_nonnull hubicka at gcc dot gnu.org
  2014-10-04 20:27 ` [Bug c++/63459] " glisse at gcc dot gnu.org
  2014-10-04 20:54 ` hubicka at gcc dot gnu.org
@ 2014-10-04 21:12 ` glisse at gcc dot gnu.org
  2014-10-06 14:50 ` rguenth at gcc dot gnu.org
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: glisse at gcc dot gnu.org @ 2014-10-04 21:12 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63459

--- Comment #3 from Marc Glisse <glisse at gcc dot gnu.org> ---
(In reply to Jan Hubicka from comment #2)
> I wonder if we can fold this earlier, for instance FRE1 has all info to do
> the job, too.

Note that this is also done in fold-const.c (tree_expr_nonzero_warnv_p). The
move to Richard's combiner may automatically make it fold earlier, though I am
not sure how recursive predicates will look like there.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/63459] operator new and returns_nonnull
  2014-10-04 19:24 [Bug c++/63459] New: operator new and returns_nonnull hubicka at gcc dot gnu.org
                   ` (2 preceding siblings ...)
  2014-10-04 21:12 ` glisse at gcc dot gnu.org
@ 2014-10-06 14:50 ` rguenth at gcc dot gnu.org
  2014-10-08 17:59 ` hubicka at ucw dot cz
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: rguenth at gcc dot gnu.org @ 2014-10-06 14:50 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63459

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
I think a method call always has this != NULL so you'd infer this != NULL
after the call with a ASSERT_EXPR.

With the pattern stuff you can't really write "any call with some nonnull
attribute on it" so you need a tree predicate for this.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/63459] operator new and returns_nonnull
  2014-10-04 19:24 [Bug c++/63459] New: operator new and returns_nonnull hubicka at gcc dot gnu.org
                   ` (3 preceding siblings ...)
  2014-10-06 14:50 ` rguenth at gcc dot gnu.org
@ 2014-10-08 17:59 ` hubicka at ucw dot cz
  2014-10-08 18:19 ` hubicka at ucw dot cz
  2014-11-29 19:34 ` glisse at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: hubicka at ucw dot cz @ 2014-10-08 17:59 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63459

--- Comment #5 from Jan Hubicka <hubicka at ucw dot cz> ---
Hi,
does something like this make sense (I also updated the DECL_BY_REFERENCE
check.
We allow to put variable at address NULL with -fno-delete-null-pointer-checks
that IMO can let me to pass it by reference.

Why this is not part of tree_expr_nonzero_p and vrp is not simply calling
it to set up the value ranges?

Honza

Index: tree-vrp.c
===================================================================
--- tree-vrp.c    (revision 215901)
+++ tree-vrp.c    (working copy)
@@ -365,6 +365,18 @@ nonnull_arg_p (const_tree arg)
   if (arg == cfun->static_chain_decl)
     return true;

+  /* THIS argument of method is always non-NULL.  */
+  if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE
+      && arg == DECL_ARGUMENTS (current_function_decl))
+    return true;
+
+  /* Parameters passed by invisible reference are also always non-NULL
+     unsless we explicitly allow symbol to have NULL address, that is
+     permitted by -fno-delete-null-pointer-checks.  */
+  if (DECL_BY_REFERENCE (arg)
+      && flag_delete_null_pointer_checks)
+    return true;
+
   fntype = TREE_TYPE (current_function_decl);
   for (attrs = TYPE_ATTRIBUTES (fntype); attrs; attrs = TREE_CHAIN (attrs))
     {
@@ -772,7 +784,8 @@ get_value_range (const_tree var)
         set_value_range_to_varying (vr);
     }
       else if (TREE_CODE (sym) == RESULT_DECL
-           && DECL_BY_REFERENCE (sym))
+           && DECL_BY_REFERENCE (sym)
+           && flag_delete_null_pointer_checks)
     set_value_range_to_nonnull (vr, TREE_TYPE (sym));
     }


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/63459] operator new and returns_nonnull
  2014-10-04 19:24 [Bug c++/63459] New: operator new and returns_nonnull hubicka at gcc dot gnu.org
                   ` (4 preceding siblings ...)
  2014-10-08 17:59 ` hubicka at ucw dot cz
@ 2014-10-08 18:19 ` hubicka at ucw dot cz
  2014-11-29 19:34 ` glisse at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: hubicka at ucw dot cz @ 2014-10-08 18:19 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63459

--- Comment #6 from Jan Hubicka <hubicka at ucw dot cz> ---
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63459
> 
> --- Comment #5 from Jan Hubicka <hubicka at ucw dot cz> ---
> Hi,
> does something like this make sense (I also updated the DECL_BY_REFERENCE
> check.
> We allow to put variable at address NULL with -fno-delete-null-pointer-checks
> that IMO can let me to pass it by reference.

Hmm, actually in C++ one always gets a local copy.  I wonder if other languages
use it, but until one is found, I guess we do not need that test.

Honza


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/63459] operator new and returns_nonnull
  2014-10-04 19:24 [Bug c++/63459] New: operator new and returns_nonnull hubicka at gcc dot gnu.org
                   ` (5 preceding siblings ...)
  2014-10-08 18:19 ` hubicka at ucw dot cz
@ 2014-11-29 19:34 ` glisse at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: glisse at gcc dot gnu.org @ 2014-11-29 19:34 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63459

--- Comment #7 from Marc Glisse <glisse at gcc dot gnu.org> ---
(In reply to Jan Hubicka from comment #0)
> It would be nice to use the fact that the default
> operator new throw exception instead of returning NULL in out of memory case.

Note that often you want to know not only that the pointer p returned by
new/malloc is non-zero, you also want to know that p+1, p+4 etc are non-zero
(see for instance the optimized dump of auto f(){return
std::vector<int>{1,2,3};} until we implement
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1748 ).


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-11-29 19:34 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-04 19:24 [Bug c++/63459] New: operator new and returns_nonnull hubicka at gcc dot gnu.org
2014-10-04 20:27 ` [Bug c++/63459] " glisse at gcc dot gnu.org
2014-10-04 20:54 ` hubicka at gcc dot gnu.org
2014-10-04 21:12 ` glisse at gcc dot gnu.org
2014-10-06 14:50 ` rguenth at gcc dot gnu.org
2014-10-08 17:59 ` hubicka at ucw dot cz
2014-10-08 18:19 ` hubicka at ucw dot cz
2014-11-29 19:34 ` glisse at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).