Diego Novillo wrote:
> int *this_never_returns_NULL (void) __attribute__ ((never_returns_null));
>
> We would not want to pin the never-null attribute to 'int *':

Well, of course.  That's why we're talking about a type *variant*.

To emphasise: this is a type variant *in the gcc internals* - i.e.
using a distinct POINTER_TYPE node.  To what extent this is reflected
at the source level is up to front-ends.

Thus:
int *this_never_returns_NULL(void) __attribute__((never_returns_null));

could be viewed as syntactic sugar for:

(int __attribute__((never_null)) *) this_never_returns_NULL(void);

[Note I'm unsure about __attribute__ and declaration syntax, so it
is possible this wouldn't work.  But that's a syntax issue, so it ignore
it in the following.]

>
> foo()
> {
>    int *p = this_never_returns_NULL ();
>    < ... use p without modifying it ... > <-- p is never NULL here.       
>    p = other_fn ();
>    < ... use p without modifying it ... >    <-- p may be NULL here.
> }

We could allow, if desired:
foo()
{
   int __attribute__((never_null)) *p = this_never_returns_NULL ();
   < ... use p without modifying it ... > <-- p is never NULL here.    
   p = other_fn (); /* error - caught by the compiler */
}

Consider:
foo()
{
   int *p;
   if (test)
     {
       p = this_never_returns_NULL ();
       < ... use p without modifying it ... >     <-- p never NULL here.
     }
   else
    {   
      p = other_fn ();
      < ... use p without modifying it ... >      <-- p may be NULL here.
    }
   ... more uses of p ...;
}

The internal SSA form might be something like:

foo()
{
   if (test)
     {
       int __attribute__((never_null)) *p_1 = this_never_returns_NULL();
       < ... use p without modifying it ... >     <-- p_1 never NULL here.
     }
   else
    {   
      int *p_2 = other_fn ();
      < ... use p without modifying it ... > <-- p_2 may be NULL here.
    }
  int *p_3 = PHI(p_1, p_2);
   ... more uses of p ...;
}
--
        --Per Bothner
[EMAIL PROTECTED]   http://per.bothner.com/

Reply via email to