1 | // RUN: %clang_cc1 -fsyntax-only -verify %s |
2 | struct S { |
3 | S(const char *) __attribute__((nonnull(2))); |
4 | |
5 | static void f(const char*, const char*) __attribute__((nonnull(1))); |
6 | |
7 | // GCC has a hidden 'this' argument in member functions, so the middle |
8 | // argument is the one that must not be null. |
9 | void g(const char*, const char*, const char*) __attribute__((nonnull(3))); |
10 | |
11 | void h(const char*) __attribute__((nonnull(1))); // \ |
12 | expected-error{{invalid for the implicit this argument}} |
13 | }; |
14 | |
15 | void test() { |
16 | S s(0); // expected-warning{{null passed}} |
17 | |
18 | s.f(0, ""); // expected-warning{{null passed}} |
19 | s.f("", 0); |
20 | s.g("", 0, ""); // expected-warning{{null passed}} |
21 | s.g(0, "", 0); |
22 | } |
23 | |
24 | namespace rdar8769025 { |
25 | __attribute__((nonnull)) void f0(int *&p); |
26 | __attribute__((nonnull)) void f1(int * const &p); |
27 | __attribute__((nonnull(2))) void f2(int i, int * const &p); |
28 | |
29 | void test_f1() { |
30 | f1(0); // expected-warning{{null passed to a callee that requires a non-null argument}} |
31 | f2(0, 0); // expected-warning{{null passed to a callee that requires a non-null argument}} |
32 | } |
33 | } |
34 | |
35 | namespace test3 { |
36 | __attribute__((nonnull(1))) void f(void *ptr); |
37 | |
38 | void g() { |
39 | f(static_cast<char*>((void*)0)); // expected-warning{{null passed}} |
40 | f(static_cast<char*>(0)); // expected-warning{{null passed}} |
41 | } |
42 | } |
43 | |
44 | namespace test4 { |
45 | struct X { |
46 | bool operator!=(const void *) const __attribute__((nonnull(2))); |
47 | }; |
48 | bool operator==(const X&, const void *) __attribute__((nonnull(2))); |
49 | |
50 | void test(const X& x) { |
51 | (void)(x == 0); // expected-warning{{null passed}} |
52 | (void)(x != 0); // expected-warning{{null passed}} |
53 | } |
54 | } |
55 | |