| // RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability,debug.ExprInspection -verify %s |
| |
| void clang_analyzer_warnIfReached(void); |
| |
| void it_takes_two(int a, int b); |
| void function_pointer_arity_mismatch(void) { |
| void(*fptr)() = it_takes_two; |
| fptr(1); // no-crash expected-warning {{Function taking 2 arguments is called with fewer (1)}} |
| // expected-warning@-1 {{passing arguments to a function without a prototype is deprecated in all versions of C and is not supported in C23}} |
| } |
| |
| void block_arity_mismatch(void) { |
| void(^b)() = ^(int a, int b) { }; |
| b(1); // no-crash expected-warning {{Block taking 2 arguments is called with fewer (1)}} |
| // expected-warning@-1 {{passing arguments to a function without a prototype is deprecated in all versions of C and is not supported in C23}} |
| } |
| |
| int *nonnull_return_annotation_indirect(void) __attribute__((returns_nonnull)); |
| int *nonnull_return_annotation_indirect(void) { |
| int *x = 0; |
| return x; // expected-warning {{Null returned from a function that is expected to return a non-null value}} |
| } |
| |
| int *nonnull_return_annotation_direct(void) __attribute__((returns_nonnull)); |
| int *nonnull_return_annotation_direct(void) { |
| return 0; // expected-warning {{Null returned from a function that is expected to return a non-null value}} |
| } // expected-warning@-1 {{null returned from function that requires a non-null return value}} |
| |
| int *nonnull_return_annotation_assumed(int* ptr) __attribute__((returns_nonnull)); |
| int *nonnull_return_annotation_assumed(int* ptr) { |
| if (ptr) { |
| return ptr; |
| } |
| return ptr; // expected-warning {{Null returned from a function that is expected to return a non-null value}} |
| } |
| |
| int *produce_nonnull_ptr(void) __attribute__((returns_nonnull)); |
| |
| __attribute__((returns_nonnull)) |
| int *cannot_return_null(void) { |
| int *x = produce_nonnull_ptr(); |
| if (!x) { |
| clang_analyzer_warnIfReached(); |
| // expected-warning@-1 {{REACHABLE}} |
| // TODO: This warning is a false positive, according to the contract of |
| // produce_nonnull_ptr, x cannot be null. |
| } |
| // Regardless of the potential state split above, x cannot be nullptr |
| // according to the produce_nonnull_ptr annotation. |
| return x; |
| // False positive: expected-warning@-1 {{Null returned from a function that is expected to return a non-null value}} |
| } |
| |
| __attribute__((returns_nonnull)) int *passthrough(int *p) { |
| return p; // no-warning: we have no evidence that `p` is null, i.e., violating the contract |
| } |
| |
| __attribute__((returns_nonnull)) int *passthrough2(int *p); |
| int *passthrough2(int *p) { |
| return p; // expected-warning{{Null returned from a function that is expected to return a non-null value}} |
| } |
| |
| void call_with_null(void) { |
| passthrough2(0); |
| } |