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/