[cfe-dev] Clang ignores nonnull attributes on pointer-to-member-function declarations
Tom Honermann
thonermann at coverity.com
Wed Jul 15 10:31:25 PDT 2015
On 07/13/2015 07:08 PM, Richard Smith wrote:
> On Mon, Jul 13, 2015 at 2:00 PM, Tom Honermann <thonermann at coverity.com
> <mailto:thonermann at coverity.com>> wrote:
>
> 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>
> <mailto: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.
>
>
> OK, we'll need to figure out how to integrate this into our
> __attribute__((nonnull)) semantics. Please do file that PR so we don't
> forget!
PR filed:
https://llvm.org/bugs/show_bug.cgi?id=24133
In researching this, I also found that Clang's behavior with regard to
nonnull attributes for parameter declarations has changed over time:
$ cat t.cpp
void f1(void (*pf)(void*) __attribute__((nonnull))) {
pf(0);
}
void f2() {
f1(0);
}
# Clang 3.4:
clang -c t.cpp
t.cpp:2:9: warning: null passed to a callee which requires a non-null
argument [-Wnonnull]
pf(0);
~^
1 warning generated.
# Clang 3.5:
clang -c t.cpp
t.cpp:5:9: warning: null passed to a callee which requires a non-null
argument [-Wnonnull]
f1(0);
~^
1 warning generated.
# Clang 3.6:
clang -c t.cpp
t.cpp:2:9: warning: null passed to a callee that requires a non-null
argument [-Wnonnull]
pf(0);
~^
t.cpp:5:9: warning: null passed to a callee that requires a non-null
argument [-Wnonnull]
f1(0);
~^
2 warnings generated.
Clang 3.4 was consistent with gcc semantics. Clang 3.5 introduced infix
nonnull attributes and created an ambiguity that was resolved in favor
of applying the attribute to the parameter declaration (changing
behavior from Clang 3.4 and breaking consistency with gcc). Clang 3.6
addressed the behavioral deviation by applying the attribute to both the
parameter declaration and the function type of the parameter. The Clang
3.6 behavior seems reasonable to me.
Tom.
More information about the cfe-dev
mailing list