This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

nonnull attribute (was: Re: Couldn't `function(arg[static 3])` imply nonnull and array size in C?)


Am Fri, 8 May 2015 11:04:22 +0000
Joseph Myers <joseph@codesourcery.com>:

> On Fri, 8 May 2015, Manuel LÃpez-IbÃÃez wrote:
> 
> > "At present, the first parameter in a function prototype must have
> > some type specifier that is not an attribute specifier; this resolves
> > an ambiguity in the interpretation of void f(int (__attribute__((foo))
> > x))"
> > https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html#Attribute-Syntax
> > 
> > But I don't understand the example given in the docs.
> 
> This means that this example is interpreted as
> 
> void f(int __attribute__((foo)) x);
> 
> and not
> 
> void f(int (*)(int __attribute__((foo)) x));
> 
> (with implicit int and adjustment of a parameter declared with function 
> type to have pointer to function type), which would be a valid parse if 
> you only consider the syntax productions without the above disambiguation.

So this is merely a syntax issue unrelated to the original problem:

void foo(__attribute__((nonnull)) int *a) { }
void bar(__attribute__((nonnull)) int (*a)(int*)) { (*a)(0); }

where the first works with clang but not with gcc (which gives
a warning) and the latter applies the attribute to the parameter
with clang, but to the pointed-to function with gcc. For clang,
to get nonnull to apply to the pointed-to function, one has to
put it into the parameter list of the pointed-to function.

So more relevant seems this quote:

"Where an attribute specifier is applied to a parameter declared as a
function or an array, it should apply to the function or array rather
than the pointer to which the parameter is implicitly converted, but
this is not yet correctly implemented."

Which may suggest that if the parameter is *not* declared as a function
or an array, it is supposed to apply to the parameter itself instead... 

But then there is also:

"For compatibility with existing code ....
If an attribute that only applies to function types is applied to a
pointer-to-function type, it is treated as applying to the pointer 
target type; "

Which I guess applies here.

So without breaking the existing behaviour of nonnull, we cannot make 
this work... We could add an entirely new attribute (e.g. nonzero)
which is not a function attribute? Or just implement 'static', but this
does not work for C++.


From reading the documentation, it seems that attributes originally
were supposed to only go with declarations and were not meant to be a
general extension to the type system. But then there is the example:

char *__attribute__((aligned(8))) *f;

which implies that now (some) attributes could work similar to type 
qualifiers. Is this the idea?


Martin






Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]