"array parameter is missing a nullability type specifier (_Nonnull, "
"_Nullable, or _Null_unspecified)">,
InGroup<NullabilityCompletenessOnArrays>;
+def note_nullability_fix_it : Note<
+ "insert '%select{_Nonnull|_Nullable|_Null_unspecified}0' if the "
+ "%select{pointer|block pointer|member pointer|array parameter}1 "
+ "%select{should never be null|may be null|should not declare nullability}0">;
def warn_nullability_inferred_on_nested_type : Warning<
"inferring '_Nonnull' for pointer type within %select{array|reference}0 is "
return file;
}
+/// Creates a fix-it to insert a C-style nullability keyword at \p pointerLoc,
+/// taking into account whitespace before and after.
+static FixItHint fixItNullability(Sema &S, SourceLocation PointerLoc,
+ NullabilityKind Nullability) {
+ assert(PointerLoc.isValid());
+
+ SmallString<32> InsertionTextBuf{" "};
+ InsertionTextBuf += getNullabilitySpelling(Nullability);
+ InsertionTextBuf += " ";
+ StringRef InsertionText = InsertionTextBuf.str();
+
+ SourceLocation FixItLoc = S.getLocForEndOfToken(PointerLoc);
+ if (const char *NextChar = S.SourceMgr.getCharacterData(FixItLoc)) {
+ if (isWhitespace(*NextChar)) {
+ InsertionText = InsertionText.drop_back();
+ } else if (NextChar[-1] == '[') {
+ if (NextChar[0] == ']')
+ InsertionText = InsertionText.drop_back().drop_front();
+ else
+ InsertionText = InsertionText.drop_front();
+ } else if (!isIdentifierBody(NextChar[0], /*allow dollar*/true) &&
+ !isIdentifierBody(NextChar[-1], /*allow dollar*/true)) {
+ InsertionText = InsertionText.drop_back().drop_front();
+ }
+ }
+
+ return FixItHint::CreateInsertion(FixItLoc, InsertionText);
+}
+
+static void emitNullabilityConsistencyWarning(Sema &S,
+ SimplePointerKind PointerKind,
+ SourceLocation PointerLoc) {
+ assert(PointerLoc.isValid());
+
+ if (PointerKind == SimplePointerKind::Array) {
+ S.Diag(PointerLoc, diag::warn_nullability_missing_array);
+ } else {
+ S.Diag(PointerLoc, diag::warn_nullability_missing)
+ << static_cast<unsigned>(PointerKind);
+ }
+
+ auto addFixIt = [&](NullabilityKind Nullability) {
+ S.Diag(PointerLoc, diag::note_nullability_fix_it)
+ << static_cast<unsigned>(Nullability)
+ << static_cast<unsigned>(PointerKind)
+ << fixItNullability(S, PointerLoc, Nullability);
+ };
+ addFixIt(NullabilityKind::Nullable);
+ addFixIt(NullabilityKind::NonNull);
+}
+
/// Complains about missing nullability if the file containing \p pointerLoc
/// has other uses of nullability (either the keywords or the \c assume_nonnull
/// pragma).
}
// Complain about missing nullability.
- if (pointerKind == SimplePointerKind::Array) {
- S.Diag(pointerLoc, diag::warn_nullability_missing_array);
- } else {
- S.Diag(pointerLoc, diag::warn_nullability_missing)
- << static_cast<unsigned>(pointerKind);
- }
+ emitNullabilityConsistencyWarning(S, pointerKind, pointerLoc);
}
/// Marks that a nullability feature has been used in the file containing
if (fileNullability.PointerLoc.isInvalid())
return;
- if (fileNullability.PointerKind ==
- static_cast<unsigned>(SimplePointerKind::Array)) {
- S.Diag(fileNullability.PointerLoc, diag::warn_nullability_missing_array);
- } else {
- S.Diag(fileNullability.PointerLoc, diag::warn_nullability_missing)
- << static_cast<unsigned>(fileNullability.PointerKind);
- }
+ auto kind = static_cast<SimplePointerKind>(fileNullability.PointerKind);
+ emitNullabilityConsistencyWarning(S, kind, fileNullability.PointerLoc);
}
/// Returns true if any of the declarator chunks before \p endIndex include a
if (pointerLoc.isValid() &&
complainAboutInferringWithinChunk !=
PointerWrappingDeclaratorKind::None) {
- SourceLocation fixItLoc = S.getLocForEndOfToken(pointerLoc);
- StringRef insertionText = " _Nonnull ";
- if (const char *nextChar = S.SourceMgr.getCharacterData(fixItLoc)) {
- if (isWhitespace(*nextChar)) {
- insertionText = insertionText.drop_back();
- } else if (!isIdentifierBody(nextChar[0], /*allow dollar*/true) &&
- !isIdentifierBody(nextChar[-1], /*allow dollar*/true)) {
- insertionText = insertionText.drop_back().drop_front();
- }
- }
-
S.Diag(pointerLoc, diag::warn_nullability_inferred_on_nested_type)
<< static_cast<int>(complainAboutInferringWithinChunk)
- << FixItHint::CreateInsertion(fixItLoc, insertionText);
+ << fixItNullability(S, pointerLoc, NullabilityKind::NonNull);
}
if (inferNullabilityInnerOnly)
--- /dev/null
+int * _Nonnull forceNullabilityWarnings(void);
+
+void arrayParameter(int x[]); // expected-warning {{array parameter is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable'}}
+// expected-note@-2 {{insert '_Nonnull'}}
+// CHECK: fix-it:"{{.*}}nullability.h":{[[@LINE-3]]:27-[[@LINE-3]]:27}:"_Nullable"
+// CHECK: fix-it:"{{.*}}nullability.h":{[[@LINE-4]]:27-[[@LINE-4]]:27}:"_Nonnull"
+
+void arrayParameterWithSize(int x[5]); // expected-warning {{array parameter is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable'}}
+// expected-note@-2 {{insert '_Nonnull'}}
+// CHECK: fix-it:"{{.*}}nullability.h":{[[@LINE-3]]:35-[[@LINE-3]]:35}:"_Nullable "
+// CHECK: fix-it:"{{.*}}nullability.h":{[[@LINE-4]]:35-[[@LINE-4]]:35}:"_Nonnull "
+
+void arrayParameterWithStar(int x[*]); // expected-warning {{array parameter is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable'}}
+// expected-note@-2 {{insert '_Nonnull'}}
+// CHECK: fix-it:"{{.*}}nullability.h":{[[@LINE-3]]:35-[[@LINE-3]]:35}:"_Nullable "
+// CHECK: fix-it:"{{.*}}nullability.h":{[[@LINE-4]]:35-[[@LINE-4]]:35}:"_Nonnull "
-// RUN: %clang_cc1 -fsyntax-only -fblocks -std=gnu++11 -verify %s
-// RUN: not %clang_cc1 -fdiagnostics-parseable-fixits -fblocks -std=gnu++11 %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -fsyntax-only -fblocks -std=gnu++11 -I %S/Inputs -verify %s
+// RUN: not %clang_cc1 -fdiagnostics-parseable-fixits -fblocks -std=gnu++11 -I %S/Inputs %s >%t.txt 2>&1
+// RUN: FileCheck %s < %t.txt
+// RUN: FileCheck %S/Inputs/nullability.h < %t.txt
+
+#include "nullability.h"
#pragma clang assume_nonnull begin
extern void *array[2]; // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull "
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull "
extern void* array2[2]; // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:13-[[@LINE-1]]:13}:" _Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:13-[[@LINE-1]]:13}:" _Nonnull"
extern void *nestedArray[2][3]; // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull "
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull "
typedef const void *CFTypeRef;
extern CFTypeRef typedefArray[2]; // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:" _Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:17-[[@LINE-1]]:17}:" _Nonnull"
extern void *&ref; // expected-warning {{inferring '_Nonnull' for pointer type within reference is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:14}:"_Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:14-[[@LINE-1]]:14}:"_Nonnull"
extern void * &ref2; // expected-warning {{inferring '_Nonnull' for pointer type within reference is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull"
extern void *&&ref3; // expected-warning {{inferring '_Nonnull' for pointer type within reference is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:14}:"_Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:14-[[@LINE-1]]:14}:"_Nonnull"
extern void * &&ref4; // expected-warning {{inferring '_Nonnull' for pointer type within reference is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull"
extern void *(&arrayRef)[2]; // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:14}:"_Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:14-[[@LINE-1]]:14}:"_Nonnull"
extern void * (&arrayRef2)[2]; // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:14-[[@LINE-1]]:14}:" _Nonnull"
extern CFTypeRef &typedefRef; // expected-warning {{inferring '_Nonnull' for pointer type within reference is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:" _Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:17-[[@LINE-1]]:17}:" _Nonnull"
extern CFTypeRef& typedefRef2; // expected-warning {{inferring '_Nonnull' for pointer type within reference is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:" _Nonnull "
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:17-[[@LINE-1]]:17}:" _Nonnull "
void arrayNameless(void *[]); // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:26-[[@LINE-1]]:26}:"_Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:26-[[@LINE-1]]:26}:"_Nonnull"
void arrayNameless2(void * []); // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:27-[[@LINE-1]]:27}:" _Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:27-[[@LINE-1]]:27}:" _Nonnull"
void arrayNamelessTypedef(CFTypeRef[]); // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:36-[[@LINE-1]]:36}:" _Nonnull "
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:36-[[@LINE-1]]:36}:" _Nonnull "
void arrayNamelessTypedef2(CFTypeRef []); // expected-warning {{inferring '_Nonnull' for pointer type within array is deprecated}}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:37-[[@LINE-1]]:37}:" _Nonnull"
+// CHECK: fix-it:"{{.*}}nullability.mm":{[[@LINE-1]]:37-[[@LINE-1]]:37}:" _Nonnull"
extern int (*pointerToArray)[2]; // no-warning
void f1(int *ptr); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
void f2(int * _Nonnull);
#include "nullability-consistency-2.h"
void f3(int *ptr) { // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
int *other = ptr; // shouldn't warn
}
class X {
void mf(int *ptr); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
int X:: *memptr; // expected-warning{{member pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the member pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the member pointer should never be null}}
};
template <typename T>
struct Typedefs {
typedef T *Base; // no-warning
typedef Base *type; // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
};
Typedefs<int> xx;
void g1(int * _Nonnull);
void g2(int (^block)(int, int)); // expected-warning{{block pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the block pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the block pointer should never be null}}
void g3(const
id // expected-warning{{missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
volatile
* // expected-warning{{missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
);
@interface SomeClass
- (nullable SomeClass *)method1;
- (void)method2:(nonnull SomeClass *)param;
@property (readonly, weak) SomeClass *property3; // expected-warning{{missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
@end
@interface SomeClass ()
@property (readonly, weak) SomeClass *property4; // expected-warning{{missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
@end
void double_declarator1(int *_Nonnull *); // expected-warning{{pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
void double_declarator1(int * * _Nonnull); // expected-warning{{pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
void suppress1(SUPPRESS_NULLABILITY_WARNING(int *) ptr); // no warning
void shouldwarn5(int *ptr); //expected-warning{{missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
void trigger5(int * _Nonnull);
int *ptr; // expected-warning {{missing a nullability type specifier}}
-
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
#pragma clang assume_nonnull begin
extern void **blah; // expected-warning 2{{missing a nullability type specifier}}
+// expected-note@-1 2 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 2 {{insert '_Nonnull' if the pointer should never be null}}
__attribute__((objc_root_class))
@interface ClassWithWeakProperties
@interface C : A
- (instancetype)init; // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
- (instancetype)initWithA:( A*)a __attribute__((objc_designated_initializer)); // expected-warning 2{{pointer is missing a nullability type specifier}}
+// expected-note@-1 2{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 2{{insert '_Nonnull' if the pointer should never be null}}
@end
#endif
void func2(mynonnull i);
void func3(int *); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
typedef void *CFTypeRef;
-void cf1(CFTypeRef * p CF_RETURNS_NOT_RETAINED); // expected-warning {{pointer is missing a nullability type specifier}}
+void cf1(CFTypeRef * p CF_RETURNS_NOT_RETAINED); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
void cf2(CFTypeRef * _Nullable p CF_RETURNS_NOT_RETAINED);
void cf3(CFTypeRef * _Nonnull p CF_RETURNS_NOT_RETAINED);
void cf7(CF_RETURNS_NOT_RETAINED CFTypeRef * _Nonnull p);
typedef CFTypeRef _Nullable *CFTypeRefPtr;
-void cfp1(CFTypeRefPtr p CF_RETURNS_NOT_RETAINED); // expected-warning {{pointer is missing a nullability type specifier}}
+void cfp1(CFTypeRefPtr p CF_RETURNS_NOT_RETAINED); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
void cfp2(CFTypeRefPtr _Nonnull p CF_RETURNS_NOT_RETAINED);
void firstThingInTheFileThatNeedsNullabilityIsAnArray(int ints[]);
#if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-2 {{array parameter is missing a nullability type specifier}}
+// expected-note@-3 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-4 {{insert '_Nonnull' if the array parameter should never be null}}
#endif
int *secondThingInTheFileThatNeedsNullabilityIsAPointer;
#if !ARRAYS_CHECKED
// expected-warning@-2 {{pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-note@-3 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-4 {{insert '_Nonnull' if the pointer should never be null}}
#endif
int *_Nonnull triggerConsistencyWarnings;
void test(
int ints[],
#if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-2 {{array parameter is missing a nullability type specifier}}
+// expected-note@-3 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-4 {{insert '_Nonnull' if the array parameter should never be null}}
#endif
void *ptrs[], // expected-warning {{pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
#if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-4 {{array parameter is missing a nullability type specifier}}
+// expected-note@-5 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-6 {{insert '_Nonnull' if the array parameter should never be null}}
#endif
void **nestedPtrs[]); // expected-warning 2 {{pointer is missing a nullability type specifier}}
+// expected-note@-1 2 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 2 {{insert '_Nonnull' if the pointer should never be null}}
#if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-4 {{array parameter is missing a nullability type specifier}}
+// expected-note@-5 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-6 {{insert '_Nonnull' if the array parameter should never be null}}
#endif
void testArraysOK(
int ints[_Nonnull],
void *ptrs[_Nonnull], // expected-warning {{pointer is missing a nullability type specifier}}
+// expected-note@-1 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 {{insert '_Nonnull' if the pointer should never be null}}
void **nestedPtrs[_Nonnull]); // expected-warning 2 {{pointer is missing a nullability type specifier}}
+// expected-note@-1 2 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 2 {{insert '_Nonnull' if the pointer should never be null}}
void testAllOK(
int ints[_Nonnull],
void * _Nullable ptrs[_Nonnull],
void nestedArrays(int x[5][1]) {}
#if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-2 {{array parameter is missing a nullability type specifier}}
+// expected-note@-3 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-4 {{insert '_Nonnull' if the array parameter should never be null}}
#endif
void nestedArraysOK(int x[_Nonnull 5][1]) {}
void typedefTest(
INTS x,
#if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-2 {{array parameter is missing a nullability type specifier}}
+// expected-note@-3 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-4 {{insert '_Nonnull' if the array parameter should never be null}}
#endif
INTS _Nonnull x2,
_Nonnull INTS x3,
INTS y[2],
#if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-2 {{array parameter is missing a nullability type specifier}}
+// expected-note@-3 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-4 {{insert '_Nonnull' if the array parameter should never be null}}
#endif
INTS y2[_Nonnull 2]);
void testAssumeNonnull(
int ints[],
#if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-2 {{array parameter is missing a nullability type specifier}}
+// expected-note@-3 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-4 {{insert '_Nonnull' if the array parameter should never be null}}
#endif
void *ptrs[],
#if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-2 {{array parameter is missing a nullability type specifier}}
+// expected-note@-3 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-4 {{insert '_Nonnull' if the array parameter should never be null}}
#endif
void **nestedPtrs[]); // expected-warning 2 {{pointer is missing a nullability type specifier}}
+// expected-note@-1 2 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 2 {{insert '_Nonnull' if the pointer should never be null}}
#if ARRAYS_CHECKED
-// expected-warning@-2 {{array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
+// expected-warning@-4 {{array parameter is missing a nullability type specifier}}
+// expected-note@-5 {{insert '_Nullable' if the array parameter may be null}}
+// expected-note@-6 {{insert '_Nonnull' if the array parameter should never be null}}
#endif
void testAssumeNonnullAllOK(
void system1(int *ptr);
#if WARN_IN_SYSTEM_HEADERS
// expected-warning@-2{{pointer is missing a nullability type specifier}}
+// expected-note@-3 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-4 {{insert '_Nonnull' if the pointer should never be null}}
#endif
void system2(int * _Nonnull);
struct X { };
void f1(int *x); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
typedef struct __attribute__((objc_bridge(NSError))) __CFError *CFErrorRef;
typedef NSError *NSErrorPtr;
A * _Null_unspecified f16(void);
void f17(CFErrorRef *error); // expected-note{{no known conversion from 'A * _Nonnull' to 'CFErrorRef _Nullable * _Nullable' (aka '__CFError **') for 1st argument}}
void f18(A **); // expected-warning 2{{pointer is missing a nullability type specifier}}
+// expected-note@-1 2 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 2 {{insert '_Nonnull' if the pointer should never be null}}
void f19(CFErrorRefPtr error); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
void g1(int (^)(int, int));
void g2(int (^ *bp)(int, int)); // expected-warning{{block pointer is missing a nullability type specifier}}
-// expected-warning@-1{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the block pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the block pointer should never be null}}
+// expected-warning@-3{{pointer is missing a nullability type specifier}}
+// expected-note@-4{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-5{{insert '_Nonnull' if the pointer should never be null}}
void g3(block_ptr *bp); // expected-warning{{block pointer is missing a nullability type specifier}}
-// expected-warning@-1{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the block pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the block pointer should never be null}}
+// expected-warning@-3{{pointer is missing a nullability type specifier}}
+// expected-note@-4{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-5{{insert '_Nonnull' if the pointer should never be null}}
void g4(int (*fp)(int, int));
void g5(int (**fp)(int, int)); // expected-warning 2{{pointer is missing a nullability type specifier}}
+// expected-note@-1 2 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 2 {{insert '_Nonnull' if the pointer should never be null}}
@interface A(Pragmas1)
+ (instancetype)aWithA:(A *)a;
- (void)method4:(NSErrorPtr *)error; // expected-note{{passing argument to parameter 'error' here}}
- (void)method5:(NSErrorPtrPtr)error;
// expected-warning@-1{{pointer is missing a nullability type specifier}}
+// expected-note@-2{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-3{{insert '_Nonnull' if the pointer should never be null}}
@property A *aProp;
@property NSError **anError; // expected-warning 2{{pointer is missing a nullability type specifier}}
+// expected-note@-1 2 {{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2 2 {{insert '_Nonnull' if the pointer should never be null}}
@end
int *global_int_ptr;
typedef int *int_ptr_2;
typedef int * // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
*int_ptr_ptr;
static inline void f30(void) {
#pragma clang assume_nonnull end
void f20(A *a); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
void f21(int_ptr x); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
void f22(A_ptr y); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
void f23(int_ptr _Nullable x);
void f24(A_ptr _Nullable y);
void f25(int_ptr_2 x); // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
@interface A(OutsidePragmas1)
+ (instancetype)aWithInt:(int)value; // expected-warning{{pointer is missing a nullability type specifier}}
+// expected-note@-1{{insert '_Nullable' if the pointer may be null}}
+// expected-note@-2{{insert '_Nonnull' if the pointer should never be null}}
@end