[RFC, PATCH] nonzero attribute, static array parameter

Martin Uecker uecker@eecs.berkeley.edu
Fri Jul 24 05:13:00 GMT 2015


Hi Marek,

sorry for taking so long to respond.

Fri, 15 May 2015 15:38:43 +0200
Marek Polacek <polacek@redhat.com>:

> On Sat, May 09, 2015 at 09:42:23AM -0700, Martin Uecker wrote:
> > here is a tentative patch to implement a new attribute nonzero,
> > which is similar to nonnull, but is not a function attribute
> > but a type attribute.
> > 
> > One reason is that nonnull is awkward to use. For this reason,
> > clang allows the use of nonnull in function parameters, but this
> > is incompatible with old and current use of this attribute in gcc
> > (though in a rather obscure use case).
> > See: https://gcc.gnu.org/ml/gcc/2015-05/msg00077.html
>  
> Sorry, I quite fail to see how such an attribute would be useful.

First of all, it makes it much simpler to implement the desired warnings
and ubsan checks when passing NULL as an array parameters with 'static'.
It avoids implementing all this argument walking code which is needed
for nonnull. If we do not want a nonzero attribute, could we then
consider an internal attribute (e.g. "non zero")?

> It seems that the nonzero warning can only ever trigger when used
> on function parameters or on a return value, much as the nonnull / 
> returns_nonnull attributes. 

So far. But in the future this could be extended to other
cases where it makes sense.

> The difference is that you can use
> the nonzero attribute on a particular function parameter, but the
> nonnull attribute has this ability as well:
> 
> __attribute__ ((nonnull (1))) void foo (int *, int *);
> void
> bar (void)
> {
>   foo (0, 0);
> }

I know. But this is ugly, cumbersome, and fragile, and some uses
are incompatible with clang. That nonnull is mis-designed
has been pointed out before:

https://gcc.gnu.org/ml/gcc/2006-04/msg00551.html

> Unlike nonnull, nonzero attribute can be attached to a typedef, but
> it doesn't seem to buy you anything you couldn't do with the nonnull /
> returns_nonnull attributes.

It is much more expressive. A nonnull pointer _type_ seems really
useful to me. Many programming languages have something like this.

> The nonzero attribute can appertain even to integer types, not only
> pointer types.  Can you give an example where this would come in handy?
> It doesn't seem too useful to me.

One example:

void assert(__attribute__((nonzero)) int i);

would give a warning if it is already known at compile time
that the expression is zero.

> 
> +void foo1(int x[__attribute__((nonzero))]);
> 
> This looks weird, 

It does look weird. But this is already documented in this way:
https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html#Attribute-Syntax

The use of 'const' and 'static' in an array declarator as
defined by ISO C99 is already weird.

> the placement of the nonzero attribute here suggests
> that the array should have at least zero elements (the same that
> int x[static 0] does), but in fact it checks that the pointer passed
> to foo1 is non-NULL, i.e. something that could be easily achieved
> with the nonnull attribute.

In many case it would be much nicer to be able to declare a 
nonzero type and use it in interfaces instead of having to
add __attribute__((nonnull(1,2,5,8))) with exactly the right
numbers to a lot of prototypes.

> > The other reason is that a nonzero type attribute is conceptually
> > much simpler and at the same time more general than the existing
> > nonnull and nonnull_return function attributes (and could replace
> > both), e.g. we can define non-zero types and diagnose all stores
> > of known constant 0 to variables of this type, use this for 
> > computing better value ranges, etc.
>  
> Why would that be useful?  What makes integer 0 special?

0 is special in many ways. In particular it represents false
in an if clause. Also, why artificially restrict it to pointers
when it is trivial to make it work for integers too?


Martin





More information about the Gcc-patches mailing list