[cfe-dev] Clang ignores nonnull attributes on pointer-to-member-function declarations
Tom Honermann
thonermann at coverity.com
Mon Jul 13 14:00:32 PDT 2015
On 07/13/2015 03:33 PM, Richard Smith wrote:
> On Mon, Jul 13, 2015 at 10:41 AM, Joerg Sonnenberger
> <joerg at britannica.bec.de <mailto:joerg at britannica.bec.de>> wrote:
>
> On Mon, Jul 13, 2015 at 11:31:54AM -0400, Tom Honermann wrote:
> > Clang (3.4-trunk) ignores nonnull attributes on pointer-to-member-function
> > declarations.
>
> You are aware that 3.4-trunk is quite old and we are about to start the
> 3.7 release cycle?
>
>
> I read that as "from version 3.4 to trunk"
And that is how I intended it.
> And it's true: clang trunk
> still behaves as described. But I'm a bit confused, because the
> referenced GCC bug report says they made this work:
>
> struct Foo;
> void foo (void (Foo::*) () __attribute__ ((nonnull)));
>
> ... where the attribute would presumably apply to the pointer-to-member,
> and the request is to support this:
>
> void (S::*pmf)(int *p1)
> __attribute__((nonnull));
>
> ... where the attribute (again, presumably) jumps over the
> pointer-to-member and applies to the pointer parameter? This does not
> seem consistent. What is the actual GCC behavior?
Interesting. It didn't occur to me that the case in the gcc bug report
is ambiguous with respect to Clang's support for infix nonnull attributes.
As specified, the attribute is either an infix attribute specifying that
the pointer-to-member-function parameter value must not be null, or it
is a non-infix attribute specifying that all of the parameters of the
target of the pointer-to-member-function must not be null.
I don't think gcc supports infix nonnull attributes, so I believe the
latter behavior is what is intended. gcc compiler warnings appear to
bear this out:
$ cat t.cpp
struct S;
void f1(S *s, void (S::*pmf)(void*) __attribute__ ((nonnull))) {
(s->*pmf)(0);
}
void f2(S *s) {
f1(s, 0);
}
$ gcc -c -Wall t.cpp
t.cpp: In function ‘void f1(S*, void (S::*)(void*))’:
t.cpp:3:16: warning: null argument where non-null required (argument 2)
[-Wnonnull]
(s->*pmf)(0);
^
Note that there is a warning when passing a null argument with the
pointer-to-member-function invocation, but not when passing a null
argument as the pointer-to-member-function value.
Tom.
More information about the cfe-dev
mailing list