]> granicus.if.org Git - clang/commitdiff
Add fix-it notes to the nullability consistency warning.
authorJordan Rose <jordan_rose@apple.com>
Mon, 19 Dec 2016 20:58:20 +0000 (20:58 +0000)
committerJordan Rose <jordan_rose@apple.com>
Mon, 19 Dec 2016 20:58:20 +0000 (20:58 +0000)
This is especially important for arrays, since no one knows the proper
syntax for putting qualifiers in arrays.

    nullability.h:3:26: warning: array parameter is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)
    void arrayParameter(int x[]);
                             ^
    nullability.h:3:26: note: insert '_Nullable' if the array parameter may be null
    void arrayParameter(int x[]);
                             ^
                              _Nullable
    nullability.h:3:26: note: insert '_Nonnull' if the array parameter should never be null
    void arrayParameter(int x[]);
                             ^
                              _Nonnull

rdar://problem/29524992

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@290132 91177308-0d34-0410-b5e6-96231b3b80d8

15 files changed:
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaType.cpp
test/FixIt/Inputs/nullability.h [new file with mode: 0644]
test/FixIt/nullability.mm
test/SemaObjCXX/Inputs/nullability-consistency-1.h
test/SemaObjCXX/Inputs/nullability-consistency-2.h
test/SemaObjCXX/Inputs/nullability-consistency-3.h
test/SemaObjCXX/Inputs/nullability-consistency-4.h
test/SemaObjCXX/Inputs/nullability-consistency-5.h
test/SemaObjCXX/Inputs/nullability-consistency-6.h
test/SemaObjCXX/Inputs/nullability-consistency-7.h
test/SemaObjCXX/Inputs/nullability-consistency-8.h
test/SemaObjCXX/Inputs/nullability-consistency-arrays.h
test/SemaObjCXX/Inputs/nullability-consistency-system/nullability-consistency-system.h
test/SemaObjCXX/Inputs/nullability-pragmas-1.h

index 73f7f4ddd6899992d8fb5025501bd7b708e1beb3..2e64f10a5e11afd8a3abb64217d2ad23ca97c1c4 100644 (file)
@@ -8770,6 +8770,10 @@ def warn_nullability_missing_array : Warning<
   "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 "
index 04668359397c81861b270fe3fbb598f4af3ef7df..eabed44c18d9d27495a7a595250550a7a510182e 100644 (file)
@@ -3441,6 +3441,57 @@ static FileID getNullabilityCompletenessCheckFileID(Sema &S,
   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).
@@ -3477,12 +3528,7 @@ static void checkNullabilityConsistency(Sema &S,
   }
 
   // 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
@@ -3507,13 +3553,8 @@ static void recordNullabilitySeen(Sema &S, SourceLocation loc) {
   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
@@ -3847,20 +3888,9 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
       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)
diff --git a/test/FixIt/Inputs/nullability.h b/test/FixIt/Inputs/nullability.h
new file mode 100644 (file)
index 0000000..5dd5dfa
--- /dev/null
@@ -0,0 +1,19 @@
+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 "
index 244906601fec43e72abd3b6e6a10fba68c466554..eb900bb4466587aba272234f4b40968553a1f936 100644 (file)
@@ -1,59 +1,63 @@
-// 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
index a99f091e0f24852de269248b33a0538373347300..f04b5692c88d934591ec251cbbfcb4f3bd2f1076 100644 (file)
@@ -1,22 +1,32 @@
 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;
index 5203146353eaa50d11a4c7c35de105288abeafa3..72f22e2ce473e4385d1ebc013f6c8ddaea7629ff 100644 (file)
@@ -1,11 +1,17 @@
 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
@@ -14,8 +20,12 @@ void g3(const
 - (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
index 520d1a4b34429721bf0027e42596829cd6f9674c..e188151364b5abdf82c8b3956ccd985b860a8d48 100644 (file)
@@ -1 +1,3 @@
 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}}
index ac227a0885bf0747095009d59ffb0ee2a7b4ea34..935c09334e312a62165d8b4db717649bb40bcdd7 100644 (file)
@@ -1 +1,3 @@
 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}}
index 1c74ab882a17fcd6c8437e5826e252d1de14436f..30666c2eebba79f4e633210d04f6cb60d8868ee6 100644 (file)
@@ -7,6 +7,8 @@
 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);
 
index d1764a87dc63dbeddab26649509506e7f1f327e7..e9b2f9b13b46fc4caf284a4071f521a2bdfe9523 100644 (file)
@@ -1,8 +1,11 @@
 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
index ddbdfada7991d2bfdd4806f9a37c3be7ae1e2c87..ed61666e6e746e2f28a3a67e398837e62368d535 100644 (file)
@@ -33,7 +33,11 @@ __attribute__((unavailable("just don't")))
 
 @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
index 2425a70356d954541f2288facca1623355548ef3..1f7131577eb52d27abf717141b14a3f916b3de71 100644 (file)
@@ -8,10 +8,14 @@ __attribute__((objc_root_class))
 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);
@@ -23,5 +27,7 @@ void cf6(CFTypeRef * _Nullable CF_RETURNS_NOT_RETAINED p);
 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);
index 900930c7a705c3dada34fa634a75057fce44e875..d0d5125bff19bc0d1f4879c7218854b13ac66af1 100644 (file)
@@ -2,12 +2,16 @@
 
 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;
@@ -15,21 +19,35 @@ 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],
@@ -57,7 +75,9 @@ void testVAListWithNullability(
 
 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]) {}
 
@@ -72,13 +92,17 @@ typedef int INTS[4];
 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]);
 
@@ -87,15 +111,23 @@ void typedefTest(
 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(
index 9161af1cf3532cbe3ce22d47f4f4f8ebe00d549e..43e29e086ab0a4a6e327220945e2a0ac56481c47 100644 (file)
@@ -3,6 +3,8 @@
 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);
index 4ac813d996181aa6d86ff4cdd855106e8811aaf0..91753ca7f3ca57d9f2e4bbf2eadb7512bc401f0b 100644 (file)
@@ -9,6 +9,8 @@ __attribute__((objc_root_class))
 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;
@@ -39,15 +41,29 @@ int * _Null_unspecified f15(void);
 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;
@@ -57,9 +73,13 @@ void g5(int (**fp)(int, int)); // expected-warning 2{{pointer is missing a nulla
 - (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;
@@ -68,6 +88,8 @@ 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) {
@@ -90,12 +112,22 @@ 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