<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW " title="NEW --- - Enable support for nonnull attributes that appertain to pointer-to-member-function declarations" href="https://urldefense.proofpoint.com/v2/url?u=https-3A__llvm.org_bugs_show-5Fbug.cgi-3Fid-3D24133&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=pF93YEPyB-J_PERP4DUZOJDzFVX5ZQ57vQk33wu0vio&m=kX3qOBfheTQVvUFcFjrLSKZvMEDpxdt8yKoFUnLU-BQ&s=71J8LDZ7qEyvWBl9tyyc9fGmHK6DAuga0uOAFqXmOnk&e=">24133</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Enable support for nonnull attributes that appertain to pointer-to-member-function declarations
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>-New Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>thonermann@coverity.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Recent versions of gcc allow application of nonnull attributes to pointer to
member function declarations:

$ cat t.cpp
struct S {
    void mf(void*);
};
void f(S *s) {
    void (S::*pmf)(void *) __attribute__((nonnull)) = &S::mf;
    (s->*pmf)(0);
}

$ gcc --version
gcc (GCC) 6.0.0 20150413 (experimental)
...

$ gcc -Wall -c t.cpp
t.cpp: In function ‘void f(S*)’:
t.cpp:6:16: warning: null argument where non-null required (argument 2)
[-Wnonnull]
     (s->*pmf)(0);
                ^

Clang (3.4-3.6, trunk) rejects such attributes:

$ clang -c t.cpp
t.cpp:5:43: warning: 'nonnull' attribute only applies to functions, methods,
and parameters [-Wignored-attributes]
    void (S::*pmf)(void *) __attribute__((nonnull)) = &S::mf;
                                          ^
1 warning generated.


gcc also allows these attributes to be specified on parameters of pointer to
member function type:

$ cat t2.cpp
struct S;
void f1(S *s, void (S::*pmf)(void*) __attribute__ ((nonnull))) {
    (s->*pmf)(0);
}
void f2(S *s) {
    f1(s, 0);
}

$ gcc -Wall -c t.cpp
t.cpp: In function ‘void f(S*)’:
t.cpp:6: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 for the function
invocation using the pointer to member function variable, but not when passing
a null argument as the pointer to member function value.  This indicates that
gcc applies the attribute to the member function type of the parameter
declaration, not to the parameter declaration itself.

Clang (3.4-3.6, trunk) rejects such attributes here as well:

$ clang -c t2.cpp
t2.cpp:2:53: warning: 'nonnull' attribute only applies to functions
[-Wignored-attributes]
void f1(S *s, void (S::*pmf)(void*) __attribute__ ((nonnull))) {
                                                    ^
1 warning generated.

Clang 3.5 added support for infix nonnull attributes on parameter declarations
that uses the above syntax.  This resulted in an ambiguity for parameters of
function pointer type; does the attribute appertain to the parameter
declaration or to the type of the declaration?  Consider this example:

$ cat t3.cpp
void f1(void (*pf)(void*) __attribute__((nonnull))) {
    pf(0);
}
void f2() {
    f1(0);
}

In Clang 3.4, the attribute appertained to the function type of the parameter
declaration (a warning is emitted for line 2).  In Clang 3.5, it appertained to
the parameter declaration (and not to the function type of the parameter
declaration - a warning is emitted for line 5).  In Clang 3.6, it appertains to
*both* the function type of the parameter and the parameter declaration
(warnings are emitted for lines 2 and 5 of t3.cpp).

Presumably, nonnull attributes on parameters of pointer to member function type
should work the same way; the attribute should apply to both the parameter and
the pointer to member function type of the parameter.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>