|
1 |
| -// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability -Wno-deprecated-non-prototype -verify %s |
| 1 | +// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability,debug.ExprInspection -verify %s |
| 2 | + |
| 3 | +void clang_analyzer_warnIfReached(void); |
2 | 4 |
|
3 | 5 | void it_takes_two(int a, int b);
|
4 |
| -void function_pointer_arity_mismatch() { |
| 6 | +void function_pointer_arity_mismatch(void) { |
5 | 7 | void(*fptr)() = it_takes_two;
|
6 | 8 | fptr(1); // no-crash expected-warning {{Function taking 2 arguments is called with fewer (1)}}
|
| 9 | + // expected-warning@-1 {{passing arguments to a function without a prototype is deprecated in all versions of C and is not supported in C23}} |
7 | 10 | }
|
8 | 11 |
|
9 |
| -void block_arity_mismatch() { |
| 12 | +void block_arity_mismatch(void) { |
10 | 13 | void(^b)() = ^(int a, int b) { };
|
11 | 14 | b(1); // no-crash expected-warning {{Block taking 2 arguments is called with fewer (1)}}
|
| 15 | + // expected-warning@-1 {{passing arguments to a function without a prototype is deprecated in all versions of C and is not supported in C23}} |
| 16 | +} |
| 17 | + |
| 18 | +int *nonnull_return_annotation_indirect(void) __attribute__((returns_nonnull)); |
| 19 | +int *nonnull_return_annotation_indirect(void) { |
| 20 | + int *x = 0; |
| 21 | + return x; // expected-warning {{Null returned from a function that is expected to return a non-null value}} |
| 22 | +} |
| 23 | + |
| 24 | +int *nonnull_return_annotation_direct(void) __attribute__((returns_nonnull)); |
| 25 | +int *nonnull_return_annotation_direct(void) { |
| 26 | + return 0; // expected-warning {{Null returned from a function that is expected to return a non-null value}} |
| 27 | +} // expected-warning@-1 {{null returned from function that requires a non-null return value}} |
| 28 | + |
| 29 | +int *nonnull_return_annotation_assumed(int* ptr) __attribute__((returns_nonnull)); |
| 30 | +int *nonnull_return_annotation_assumed(int* ptr) { |
| 31 | + if (ptr) { |
| 32 | + return ptr; |
| 33 | + } |
| 34 | + return ptr; // expected-warning {{Null returned from a function that is expected to return a non-null value}} |
| 35 | +} |
| 36 | + |
| 37 | +int *produce_nonnull_ptr(void) __attribute__((returns_nonnull)); |
| 38 | + |
| 39 | +__attribute__((returns_nonnull)) |
| 40 | +int *cannot_return_null(void) { |
| 41 | + int *x = produce_nonnull_ptr(); |
| 42 | + if (!x) { |
| 43 | + clang_analyzer_warnIfReached(); |
| 44 | + // expected-warning@-1 {{REACHABLE}} |
| 45 | + // TODO: This warning is a false positive, according to the contract of |
| 46 | + // produce_nonnull_ptr, x cannot be null. |
| 47 | + } |
| 48 | + // Regardless of the potential state split above, x cannot be nullptr |
| 49 | + // according to the produce_nonnull_ptr annotation. |
| 50 | + return x; |
| 51 | + // False positive: expected-warning@-1 {{Null returned from a function that is expected to return a non-null value}} |
| 52 | +} |
| 53 | + |
| 54 | +__attribute__((returns_nonnull)) int *passthrough(int *p) { |
| 55 | + return p; // no-warning: we have no evidence that `p` is null, i.e., violating the contract |
| 56 | +} |
| 57 | + |
| 58 | +__attribute__((returns_nonnull)) int *passthrough2(int *p); |
| 59 | +int *passthrough2(int *p) { |
| 60 | + return p; // expected-warning{{Null returned from a function that is expected to return a non-null value}} |
| 61 | +} |
| 62 | + |
| 63 | +void call_with_null(void) { |
| 64 | + passthrough2(0); |
12 | 65 | }
|
0 commit comments