This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
nonnull attribute (was: Re: Couldn't `function(arg[static 3])` imply nonnull and array size in C?)
- From: Martin Uecker <uecker at eecs dot berkeley dot edu>
- To: Joseph Myers <joseph at codesourcery dot com>
- Cc: Manuel LÃpez-IbÃÃez <lopezibanez at gmail dot com>, GCC Development <gcc at gcc dot gnu dot org>, Jason Merrill <jason at redhat dot com>
- Date: Fri, 8 May 2015 11:59:45 -0700
- Subject: nonnull attribute (was: Re: Couldn't `function(arg[static 3])` imply nonnull and array size in C?)
- Authentication-results: sourceware.org; auth=none
- References: <CAEcf3Nzxt=uATHYdYu+aLBoKaB8Wyy=AztF=ZXn-atKpKhVU3Q at mail dot gmail dot com> <20150503224039 dot 28ab0404 at lemur> <55479E41 dot 2070108 at gmail dot com> <20150507105144 dot 277cc59b at lemur> <CAESRpQDGdrshKp21GrZEJsOTST5C530=j=VR=116NVEyvj-ieA at mail dot gmail dot com> <alpine dot DEB dot 2 dot 10 dot 1505081056080 dot 20373 at digraph dot polyomino dot org dot uk>
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