mirror of https://github.com/microsoft/clang.git
Replace __double_underscored type nullability qualifiers with _Uppercase_underscored
Addresses a conflict with glibc's __nonnull macro by renaming the type nullability qualifiers as follows: __nonnull -> _Nonnull __nullable -> _Nullable __null_unspecified -> _Null_unspecified This is the major part of rdar://problem/21530726, but does not yet provide the Darwin-specific behavior for the old names. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@240596 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1e6e9d1a37
commit
673b679df9
|
@ -962,17 +962,17 @@ def ReturnsNonNull : InheritableAttr {
|
|||
|
||||
// Nullability type attributes.
|
||||
def TypeNonNull : TypeAttr {
|
||||
let Spellings = [Keyword<"__nonnull">];
|
||||
let Spellings = [Keyword<"_Nonnull">];
|
||||
let Documentation = [TypeNonNullDocs];
|
||||
}
|
||||
|
||||
def TypeNullable : TypeAttr {
|
||||
let Spellings = [Keyword<"__nullable">];
|
||||
let Spellings = [Keyword<"_Nullable">];
|
||||
let Documentation = [TypeNullableDocs];
|
||||
}
|
||||
|
||||
def TypeNullUnspecified : TypeAttr {
|
||||
let Spellings = [Keyword<"__null_unspecified">];
|
||||
let Spellings = [Keyword<"_Null_unspecified">];
|
||||
let Documentation = [TypeNullUnspecifiedDocs];
|
||||
}
|
||||
|
||||
|
|
|
@ -1456,22 +1456,22 @@ cannot point to the private address space.
|
|||
|
||||
def NullabilityDocs : DocumentationCategory<"Nullability Attributes"> {
|
||||
let Content = [{
|
||||
Whether a particular pointer may be "null" is an important concern when working with pointers in the C family of languages. The various nullability attributes indicate whether a particular pointer can be null or not, which makes APIs more expressive and can help static analysis tools identify bugs involving null pointers. Clang supports several kinds of nullability attributes: the ``nonnull`` and ``returns_nonnull`` attributes indicate which function or method parameters and result types can never be null, while nullability type qualifiers indicate which pointer types can be null (``__nullable``) or cannot be null (``__nonnull``).
|
||||
Whether a particular pointer may be "null" is an important concern when working with pointers in the C family of languages. The various nullability attributes indicate whether a particular pointer can be null or not, which makes APIs more expressive and can help static analysis tools identify bugs involving null pointers. Clang supports several kinds of nullability attributes: the ``nonnull`` and ``returns_nonnull`` attributes indicate which function or method parameters and result types can never be null, while nullability type qualifiers indicate which pointer types can be null (``_Nullable``) or cannot be null (``_Nonnull``).
|
||||
|
||||
The nullability (type) qualifiers express whether a value of a given pointer type can be null (the ``__nullable`` qualifier), doesn't have a defined meaning for null (the ``__nonnull`` qualifier), or for which the purpose of null is unclear (the ``__null_unspecified`` qualifier). Because nullability qualifiers are expressed within the type system, they are more general than the ``nonnull`` and ``returns_nonnull`` attributes, allowing one to express (for example) a nullable pointer to an array of nonnull pointers. Nullability qualifiers are written to the right of the pointer to which they apply. For example:
|
||||
The nullability (type) qualifiers express whether a value of a given pointer type can be null (the ``_Nullable`` qualifier), doesn't have a defined meaning for null (the ``_Nonnull`` qualifier), or for which the purpose of null is unclear (the ``_Null_unspecified`` qualifier). Because nullability qualifiers are expressed within the type system, they are more general than the ``nonnull`` and ``returns_nonnull`` attributes, allowing one to express (for example) a nullable pointer to an array of nonnull pointers. Nullability qualifiers are written to the right of the pointer to which they apply. For example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
// No meaningful result when 'ptr' is null (here, it happens to be undefined behavior).
|
||||
int fetch(int * __nonnull ptr) { return *ptr; }
|
||||
int fetch(int * _Nonnull ptr) { return *ptr; }
|
||||
|
||||
// 'ptr' may be null.
|
||||
int fetch_or_zero(int * __nullable ptr) {
|
||||
int fetch_or_zero(int * _Nullable ptr) {
|
||||
return ptr ? *ptr : 0;
|
||||
}
|
||||
|
||||
// A nullable pointer to non-null pointers to const characters.
|
||||
const char *join_strings(const char * __nonnull * __nullable strings, unsigned n);
|
||||
const char *join_strings(const char * _Nonnull * _Nullable strings, unsigned n);
|
||||
|
||||
In Objective-C, there is an alternate spelling for the nullability qualifiers that can be used in Objective-C methods and properties using context-sensitive, non-underscored keywords. For example:
|
||||
|
||||
|
@ -1487,27 +1487,27 @@ In Objective-C, there is an alternate spelling for the nullability qualifiers th
|
|||
|
||||
def TypeNonNullDocs : Documentation {
|
||||
let Category = NullabilityDocs;
|
||||
let Heading = "__nonnull";
|
||||
let Heading = "_Nonnull";
|
||||
let Content = [{
|
||||
The ``__nonnull`` nullability qualifier indicates that null is not a meaningful value for a value of the ``__nonnull`` pointer type. For example, given a declaration such as:
|
||||
The ``_Nonnull`` nullability qualifier indicates that null is not a meaningful value for a value of the ``_Nonnull`` pointer type. For example, given a declaration such as:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int fetch(int * __nonnull ptr);
|
||||
int fetch(int * _Nonnull ptr);
|
||||
|
||||
a caller of ``fetch`` should not provide a null value, and the compiler will produce a warning if it sees a literal null value passed to ``fetch``. Note that, unlike the declaration attribute ``nonnull``, the presence of ``__nonnull`` does not imply that passing null is undefined behavior: ``fetch`` is free to consider null undefined behavior or (perhaps for backward-compatibility reasons) defensively handle null.
|
||||
a caller of ``fetch`` should not provide a null value, and the compiler will produce a warning if it sees a literal null value passed to ``fetch``. Note that, unlike the declaration attribute ``nonnull``, the presence of ``_Nonnull`` does not imply that passing null is undefined behavior: ``fetch`` is free to consider null undefined behavior or (perhaps for backward-compatibility reasons) defensively handle null.
|
||||
}];
|
||||
}
|
||||
|
||||
def TypeNullableDocs : Documentation {
|
||||
let Category = NullabilityDocs;
|
||||
let Heading = "__nullable";
|
||||
let Heading = "_Nullable";
|
||||
let Content = [{
|
||||
The ``__nullable`` nullability qualifier indicates that a value of the ``__nullable`` pointer type can be null. For example, given:
|
||||
The ``_Nullable`` nullability qualifier indicates that a value of the ``_Nullable`` pointer type can be null. For example, given:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int fetch_or_zero(int * __nullable ptr);
|
||||
int fetch_or_zero(int * _Nullable ptr);
|
||||
|
||||
a caller of ``fetch_or_zero`` can provide null.
|
||||
}];
|
||||
|
@ -1515,9 +1515,9 @@ a caller of ``fetch_or_zero`` can provide null.
|
|||
|
||||
def TypeNullUnspecifiedDocs : Documentation {
|
||||
let Category = NullabilityDocs;
|
||||
let Heading = "__null_unspecified";
|
||||
let Heading = "_Null_unspecified";
|
||||
let Content = [{
|
||||
The ``__null_unspecified`` nullability qualifier indicates that neither the ``__nonnull`` nor ``__nullable`` qualifiers make sense for a particular pointer type. It is used primarily to indicate that the role of null with specific pointers in a nullability-annotated header is unclear, e.g., due to overly-complex implementations or historical factors with a long-lived API.
|
||||
The ``_Null_unspecified`` nullability qualifier indicates that neither the ``_Nonnull`` nor ``_Nullable`` qualifiers make sense for a particular pointer type. It is used primarily to indicate that the role of null with specific pointers in a nullability-annotated header is unclear, e.g., due to overly-complex implementations or historical factors with a long-lived API.
|
||||
}];
|
||||
}
|
||||
|
||||
|
@ -1547,7 +1547,7 @@ Clang also allows the ``nonnull`` attribute to be placed directly on a function
|
|||
extern void * my_memcpy (void *dest __attribute__((nonnull)),
|
||||
const void *src __attribute__((nonnull)), size_t len);
|
||||
|
||||
Note that the ``nonnull`` attribute indicates that passing null to a non-null parameter is undefined behavior, which the optimizer may take advantage of to, e.g., remove null checks. The ``__nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable.
|
||||
Note that the ``nonnull`` attribute indicates that passing null to a non-null parameter is undefined behavior, which the optimizer may take advantage of to, e.g., remove null checks. The ``_Nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable.
|
||||
}];
|
||||
}
|
||||
|
||||
|
@ -1561,6 +1561,6 @@ The ``returns_nonnull`` attribute indicates that a particular function (or Objec
|
|||
|
||||
extern void * malloc (size_t size) __attribute__((returns_nonnull));
|
||||
|
||||
The ``returns_nonnull`` attribute implies that returning a null pointer is undefined behavior, which the optimizer may take advantage of. The ``__nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable
|
||||
The ``returns_nonnull`` attribute implies that returning a null pointer is undefined behavior, which the optimizer may take advantage of. The ``_Nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable
|
||||
}];
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "clang/Basic/DiagnosticIDs.h"
|
||||
#include "clang/Basic/DiagnosticOptions.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/Specifiers.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
|
@ -1107,6 +1108,13 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
|||
return DB;
|
||||
}
|
||||
|
||||
/// A nullability kind paired with a bit indicating whether it used a
|
||||
/// context-sensitive keyword.
|
||||
typedef std::pair<NullabilityKind, bool> DiagNullabilityKind;
|
||||
|
||||
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
DiagNullabilityKind nullability);
|
||||
|
||||
inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc,
|
||||
unsigned DiagID) {
|
||||
assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!");
|
||||
|
|
|
@ -102,31 +102,21 @@ def err_enum_template : Error<"enumeration cannot be a template">;
|
|||
let CategoryName = "Nullability Issue" in {
|
||||
|
||||
def warn_nullability_duplicate : Warning<
|
||||
"duplicate nullability specifier "
|
||||
"'%select{__|}1%select{nonnull|nullable|null_unspecified}0'">,
|
||||
"duplicate nullability specifier %0">,
|
||||
InGroup<Nullability>;
|
||||
|
||||
def warn_conflicting_nullability_attr_overriding_ret_types : Warning<
|
||||
"conflicting nullability specifier on return types, "
|
||||
"'%select{%select{__|}1nonnull|"
|
||||
"%select{__|}1nullable|%select{__|}1null_unspecified}0' "
|
||||
"conflicts with existing specifier '%select{%select{__|}3nonnull|"
|
||||
"%select{__|}3nullable|%select{__|}3null_unspecified}2'">,
|
||||
"conflicting nullability specifier on return types, %0 "
|
||||
"conflicts with existing specifier %1">,
|
||||
InGroup<Nullability>;
|
||||
|
||||
def warn_conflicting_nullability_attr_overriding_param_types : Warning<
|
||||
"conflicting nullability specifier on parameter types, "
|
||||
"'%select{%select{__|}1nonnull|"
|
||||
"%select{__|}1nullable|%select{__|}1null_unspecified}0' "
|
||||
"conflicts with existing specifier '%select{%select{__|}3nonnull|"
|
||||
"%select{__|}3nullable|%select{__|}3null_unspecified}2'">,
|
||||
"conflicting nullability specifier on parameter types, %0 "
|
||||
"conflicts with existing specifier %1">,
|
||||
InGroup<Nullability>;
|
||||
|
||||
def err_nullability_conflicting : Error<
|
||||
"nullability specifier "
|
||||
"'%select{__|}1%select{nonnull|nullable|null_unspecified}0' conflicts with "
|
||||
"existing specifier '%select{__|}3%select{nonnull|nullable|"
|
||||
"null_unspecified}2'">;
|
||||
"nullability specifier %0 conflicts with existing specifier %1">;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -7679,28 +7679,21 @@ def warn_profile_data_unprofiled : Warning<
|
|||
let CategoryName = "Nullability Issue" in {
|
||||
|
||||
def warn_mismatched_nullability_attr : Warning<
|
||||
"nullability specifier "
|
||||
"'%select{__|}1%select{nonnull|nullable|null_unspecified}0' "
|
||||
"conflicts with existing specifier "
|
||||
"'%select{__|}3%select{nonnull|nullable|null_unspecified}2'">,
|
||||
"nullability specifier %0 conflicts with existing specifier %1">,
|
||||
InGroup<Nullability>;
|
||||
|
||||
def warn_nullability_declspec : Warning<
|
||||
"nullability specifier "
|
||||
"'%select{__nonnull|__nullable|__null_unspecified}0' cannot be applied "
|
||||
"nullability specifier %0 cannot be applied "
|
||||
"to non-pointer type %1; did you mean to apply the specifier to the "
|
||||
"%select{pointer|block pointer|member pointer|function pointer|"
|
||||
"member function pointer}2?">,
|
||||
InGroup<NullabilityDeclSpec>,
|
||||
DefaultError;
|
||||
|
||||
def note_nullability_here : Note<
|
||||
"'%select{__nonnull|__nullable|__null_unspecified}0' specified here">;
|
||||
def note_nullability_here : Note<"%0 specified here">;
|
||||
|
||||
def err_nullability_nonpointer : Error<
|
||||
"nullability specifier "
|
||||
"'%select{__|}1%select{nonnull|nullable|null_unspecified}0' cannot be applied "
|
||||
"to non-pointer type %2">;
|
||||
"nullability specifier %0 cannot be applied to non-pointer type %1">;
|
||||
|
||||
def warn_nullability_lost : Warning<
|
||||
"implicit conversion from nullable pointer %0 to non-nullable pointer "
|
||||
|
@ -7708,12 +7701,9 @@ def warn_nullability_lost : Warning<
|
|||
InGroup<NullableToNonNullConversion>, DefaultIgnore;
|
||||
|
||||
def err_nullability_cs_multilevel : Error<
|
||||
"nullability keyword "
|
||||
"'%select{nonnull|nullable|null_unspecified}0' cannot be applied to "
|
||||
"multi-level pointer type %1">;
|
||||
"nullability keyword %0 cannot be applied to multi-level pointer type %1">;
|
||||
def note_nullability_type_specifier : Note<
|
||||
"use nullability type specifier "
|
||||
"'%select{__nonnull|__nullable|__null_unspecified}0' to affect the innermost "
|
||||
"use nullability type specifier %0 to affect the innermost "
|
||||
"pointer type of %1">;
|
||||
|
||||
def warn_null_resettable_setter : Warning<
|
||||
|
@ -7722,7 +7712,7 @@ def warn_null_resettable_setter : Warning<
|
|||
|
||||
def warn_nullability_missing : Warning<
|
||||
"%select{pointer|block pointer|member pointer}0 is missing a nullability "
|
||||
"type specifier (__nonnull, __nullable, or __null_unspecified)">,
|
||||
"type specifier (_Nonnull, _Nullable, or _Null_unspecified)">,
|
||||
InGroup<NullabilityCompleteness>;
|
||||
|
||||
}
|
||||
|
|
|
@ -257,7 +257,8 @@ namespace clang {
|
|||
};
|
||||
|
||||
/// Retrieve the spelling of the given nullability kind.
|
||||
llvm::StringRef getNullabilitySpelling(NullabilityKind kind);
|
||||
llvm::StringRef getNullabilitySpelling(NullabilityKind kind,
|
||||
bool isContextSensitive = false);
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_BASIC_SPECIFIERS_H
|
||||
|
|
|
@ -549,9 +549,9 @@ ALIAS("__volatile" , volatile , KEYALL)
|
|||
ALIAS("__volatile__" , volatile , KEYALL)
|
||||
|
||||
// Type nullability.
|
||||
KEYWORD(__nonnull , KEYALL)
|
||||
KEYWORD(__nullable , KEYALL)
|
||||
KEYWORD(__null_unspecified , KEYALL)
|
||||
KEYWORD(_Nonnull , KEYALL)
|
||||
KEYWORD(_Nullable , KEYALL)
|
||||
KEYWORD(_Null_unspecified , KEYALL)
|
||||
|
||||
// Microsoft extensions which should be disabled in strict conformance mode
|
||||
KEYWORD(__ptr64 , KEYMS)
|
||||
|
|
|
@ -303,7 +303,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
/// Retrieve the underscored keyword (__nonnull, __nullable) that corresponds
|
||||
/// Retrieve the underscored keyword (_Nonnull, _Nullable) that corresponds
|
||||
/// to the given nullability kind.
|
||||
IdentifierInfo *getNullabilityKeyword(NullabilityKind nullability) {
|
||||
return Actions.getNullabilityKeyword(nullability);
|
||||
|
|
|
@ -2978,7 +2978,7 @@ public:
|
|||
bool SynthesizeProperties);
|
||||
|
||||
/// Diagnose any null-resettable synthesized setters.
|
||||
void diagnoseNullResettableSynthesizedSetters(ObjCImplDecl *impDecl);
|
||||
void diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl);
|
||||
|
||||
/// DefaultSynthesizeProperties - This routine default synthesizes all
|
||||
/// properties which must be synthesized in the class's \@implementation.
|
||||
|
@ -8854,9 +8854,9 @@ private:
|
|||
mutable IdentifierInfo *Ident___float128;
|
||||
|
||||
/// Nullability type specifiers.
|
||||
IdentifierInfo *Ident___nonnull = nullptr;
|
||||
IdentifierInfo *Ident___nullable = nullptr;
|
||||
IdentifierInfo *Ident___null_unspecified = nullptr;
|
||||
IdentifierInfo *Ident__Nonnull = nullptr;
|
||||
IdentifierInfo *Ident__Nullable = nullptr;
|
||||
IdentifierInfo *Ident__Null_unspecified = nullptr;
|
||||
|
||||
IdentifierInfo *Ident_NSError = nullptr;
|
||||
|
||||
|
|
|
@ -954,9 +954,8 @@ void DeclPrinter::PrintObjCMethodType(ASTContext &Ctx,
|
|||
if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_Oneway)
|
||||
Out << "oneway ";
|
||||
if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_CSNullability) {
|
||||
if (auto nullability = AttributedType::stripOuterNullability(T)) {
|
||||
Out << getNullabilitySpelling(*nullability).substr(2) << ' ';
|
||||
}
|
||||
if (auto nullability = AttributedType::stripOuterNullability(T))
|
||||
Out << getNullabilitySpelling(*nullability, true) << ' ';
|
||||
}
|
||||
|
||||
Out << Ctx.getUnqualifiedObjCPointerType(T).getAsString(Policy);
|
||||
|
@ -1207,7 +1206,7 @@ void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
|
|||
Out << (first ? ' ' : ',') << "null_resettable";
|
||||
} else {
|
||||
Out << (first ? ' ' : ',')
|
||||
<< getNullabilitySpelling(*nullability).substr(2);
|
||||
<< getNullabilitySpelling(*nullability, true);
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
|
|
|
@ -1147,11 +1147,11 @@ void TypePrinter::printAttributedBefore(const AttributedType *T,
|
|||
T->getAttrKind() == AttributedType::attr_nullable ||
|
||||
T->getAttrKind() == AttributedType::attr_null_unspecified) {
|
||||
if (T->getAttrKind() == AttributedType::attr_nonnull)
|
||||
OS << " __nonnull";
|
||||
OS << " _Nonnull";
|
||||
else if (T->getAttrKind() == AttributedType::attr_nullable)
|
||||
OS << " __nullable";
|
||||
OS << " _Nullable";
|
||||
else if (T->getAttrKind() == AttributedType::attr_null_unspecified)
|
||||
OS << " __null_unspecified";
|
||||
OS << " _Null_unspecified";
|
||||
else
|
||||
llvm_unreachable("unhandled nullability");
|
||||
spaceBeforePlaceHolder(OS);
|
||||
|
@ -1186,11 +1186,11 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
|
|||
T->getAttrKind() == AttributedType::attr_nullable ||
|
||||
T->getAttrKind() == AttributedType::attr_null_unspecified) {
|
||||
if (T->getAttrKind() == AttributedType::attr_nonnull)
|
||||
OS << " __nonnull";
|
||||
OS << " _Nonnull";
|
||||
else if (T->getAttrKind() == AttributedType::attr_nullable)
|
||||
OS << " __nullable";
|
||||
OS << " _Nullable";
|
||||
else if (T->getAttrKind() == AttributedType::attr_null_unspecified)
|
||||
OS << " __null_unspecified";
|
||||
OS << " _Null_unspecified";
|
||||
else
|
||||
llvm_unreachable("unhandled nullability");
|
||||
|
||||
|
|
|
@ -24,6 +24,27 @@
|
|||
|
||||
using namespace clang;
|
||||
|
||||
const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
|
||||
DiagNullabilityKind nullability) {
|
||||
StringRef string;
|
||||
switch (nullability.first) {
|
||||
case NullabilityKind::NonNull:
|
||||
string = nullability.second ? "'nonnull'" : "'_Nonnull'";
|
||||
break;
|
||||
|
||||
case NullabilityKind::Nullable:
|
||||
string = nullability.second ? "'nullable'" : "'_Nullable'";
|
||||
break;
|
||||
|
||||
case NullabilityKind::Unspecified:
|
||||
string = nullability.second ? "'null_unspecified'" : "'_Null_unspecified'";
|
||||
break;
|
||||
}
|
||||
|
||||
DB.AddString(string);
|
||||
return DB;
|
||||
}
|
||||
|
||||
static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT,
|
||||
StringRef Modifier, StringRef Argument,
|
||||
ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
|
||||
|
|
|
@ -647,16 +647,17 @@ const char *clang::getOperatorSpelling(OverloadedOperatorKind Operator) {
|
|||
llvm_unreachable("Invalid OverloadedOperatorKind!");
|
||||
}
|
||||
|
||||
StringRef clang::getNullabilitySpelling(NullabilityKind kind) {
|
||||
StringRef clang::getNullabilitySpelling(NullabilityKind kind,
|
||||
bool isContextSensitive) {
|
||||
switch (kind) {
|
||||
case NullabilityKind::NonNull:
|
||||
return "__nonnull";
|
||||
return isContextSensitive ? "nonnull" : "_Nonnull";
|
||||
|
||||
case NullabilityKind::Nullable:
|
||||
return "__nullable";
|
||||
return isContextSensitive ? "nullable" : "_Nullable";
|
||||
|
||||
case NullabilityKind::Unspecified:
|
||||
return "__null_unspecified";
|
||||
return isContextSensitive ? "null_unspecified" : "_Null_unspecified";
|
||||
}
|
||||
llvm_unreachable("Unknown nullability kind.");
|
||||
}
|
||||
|
|
|
@ -691,9 +691,9 @@ void Parser::ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs) {
|
|||
// Treat these like attributes, even though they're type specifiers.
|
||||
while (true) {
|
||||
switch (Tok.getKind()) {
|
||||
case tok::kw___nonnull:
|
||||
case tok::kw___nullable:
|
||||
case tok::kw___null_unspecified: {
|
||||
case tok::kw__Nonnull:
|
||||
case tok::kw__Nullable:
|
||||
case tok::kw__Null_unspecified: {
|
||||
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
|
||||
SourceLocation AttrNameLoc = ConsumeToken();
|
||||
if (!getLangOpts().ObjC1)
|
||||
|
@ -3076,9 +3076,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
continue;
|
||||
|
||||
// Nullability type specifiers.
|
||||
case tok::kw___nonnull:
|
||||
case tok::kw___nullable:
|
||||
case tok::kw___null_unspecified:
|
||||
case tok::kw__Nonnull:
|
||||
case tok::kw__Nullable:
|
||||
case tok::kw__Null_unspecified:
|
||||
ParseNullabilityTypeSpecifiers(DS.getAttributes());
|
||||
continue;
|
||||
|
||||
|
@ -4326,9 +4326,9 @@ bool Parser::isTypeSpecifierQualifier() {
|
|||
case tok::kw___pascal:
|
||||
case tok::kw___unaligned:
|
||||
|
||||
case tok::kw___nonnull:
|
||||
case tok::kw___nullable:
|
||||
case tok::kw___null_unspecified:
|
||||
case tok::kw__Nonnull:
|
||||
case tok::kw__Nullable:
|
||||
case tok::kw__Null_unspecified:
|
||||
|
||||
case tok::kw___private:
|
||||
case tok::kw___local:
|
||||
|
@ -4503,9 +4503,9 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
|
|||
case tok::kw___pascal:
|
||||
case tok::kw___unaligned:
|
||||
|
||||
case tok::kw___nonnull:
|
||||
case tok::kw___nullable:
|
||||
case tok::kw___null_unspecified:
|
||||
case tok::kw__Nonnull:
|
||||
case tok::kw__Nullable:
|
||||
case tok::kw__Null_unspecified:
|
||||
|
||||
case tok::kw___private:
|
||||
case tok::kw___local:
|
||||
|
@ -4738,9 +4738,9 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, unsigned AttrReqs,
|
|||
goto DoneWithTypeQuals;
|
||||
|
||||
// Nullability type specifiers.
|
||||
case tok::kw___nonnull:
|
||||
case tok::kw___nullable:
|
||||
case tok::kw___null_unspecified:
|
||||
case tok::kw__Nonnull:
|
||||
case tok::kw__Nullable:
|
||||
case tok::kw__Null_unspecified:
|
||||
ParseNullabilityTypeSpecifiers(DS.getAttributes());
|
||||
continue;
|
||||
|
||||
|
|
|
@ -557,14 +557,14 @@ static void diagnoseRedundantPropertyNullability(Parser &P,
|
|||
SourceLocation nullabilityLoc){
|
||||
if (DS.getNullability() == nullability) {
|
||||
P.Diag(nullabilityLoc, diag::warn_nullability_duplicate)
|
||||
<< static_cast<unsigned>(nullability) << true
|
||||
<< DiagNullabilityKind(nullability, true)
|
||||
<< SourceRange(DS.getNullabilityLoc());
|
||||
return;
|
||||
}
|
||||
|
||||
P.Diag(nullabilityLoc, diag::err_nullability_conflicting)
|
||||
<< static_cast<unsigned>(nullability) << true
|
||||
<< static_cast<unsigned>(DS.getNullability()) << true
|
||||
<< DiagNullabilityKind(nullability, true)
|
||||
<< DiagNullabilityKind(DS.getNullability(), true)
|
||||
<< SourceRange(DS.getNullabilityLoc());
|
||||
}
|
||||
|
||||
|
|
|
@ -632,8 +632,8 @@ Parser::TPResult Parser::TryParsePtrOperatorSeq() {
|
|||
// ptr-operator
|
||||
ConsumeToken();
|
||||
while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
|
||||
tok::kw___nonnull, tok::kw___nullable,
|
||||
tok::kw___null_unspecified))
|
||||
tok::kw__Nonnull, tok::kw__Nullable,
|
||||
tok::kw__Null_unspecified))
|
||||
ConsumeToken();
|
||||
} else {
|
||||
return TPResult::True;
|
||||
|
@ -1276,9 +1276,9 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
|
|||
case tok::kw___ptr32:
|
||||
case tok::kw___forceinline:
|
||||
case tok::kw___unaligned:
|
||||
case tok::kw___nonnull:
|
||||
case tok::kw___nullable:
|
||||
case tok::kw___null_unspecified:
|
||||
case tok::kw__Nonnull:
|
||||
case tok::kw__Nullable:
|
||||
case tok::kw__Null_unspecified:
|
||||
return TPResult::True;
|
||||
|
||||
// Borland
|
||||
|
|
|
@ -1343,9 +1343,9 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts,
|
|||
}
|
||||
|
||||
// Nullability
|
||||
Results.AddResult(Result("__nonnull", CCP_Type));
|
||||
Results.AddResult(Result("__null_unspecified", CCP_Type));
|
||||
Results.AddResult(Result("__nullable", CCP_Type));
|
||||
Results.AddResult(Result("_Nonnull", CCP_Type));
|
||||
Results.AddResult(Result("_Null_unspecified", CCP_Type));
|
||||
Results.AddResult(Result("_Nullable", CCP_Type));
|
||||
}
|
||||
|
||||
static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
|
||||
|
|
|
@ -2472,13 +2472,15 @@ static void mergeParamDeclTypes(ParmVarDecl *NewParam,
|
|||
if (auto Oldnullability = OldParam->getType()->getNullability(S.Context)) {
|
||||
if (auto Newnullability = NewParam->getType()->getNullability(S.Context)) {
|
||||
if (*Oldnullability != *Newnullability) {
|
||||
unsigned unsNewnullability = static_cast<unsigned>(*Newnullability);
|
||||
unsigned unsOldnullability = static_cast<unsigned>(*Oldnullability);
|
||||
S.Diag(NewParam->getLocation(), diag::warn_mismatched_nullability_attr)
|
||||
<< unsNewnullability
|
||||
<< ((NewParam->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability) != 0)
|
||||
<< unsOldnullability
|
||||
<< ((OldParam->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability) != 0);
|
||||
<< DiagNullabilityKind(
|
||||
*Newnullability,
|
||||
((NewParam->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability)
|
||||
!= 0))
|
||||
<< DiagNullabilityKind(
|
||||
*Oldnullability,
|
||||
((OldParam->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability)
|
||||
!= 0));
|
||||
S.Diag(OldParam->getLocation(), diag::note_previous_declaration);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -1400,16 +1400,20 @@ static bool CheckMethodOverrideReturn(Sema &S,
|
|||
!S.Context.hasSameNullabilityTypeQualifier(MethodImpl->getReturnType(),
|
||||
MethodDecl->getReturnType(),
|
||||
false)) {
|
||||
unsigned unsNullabilityMethodImpl =
|
||||
static_cast<unsigned>(*MethodImpl->getReturnType()->getNullability(S.Context));
|
||||
unsigned unsNullabilityMethodDecl =
|
||||
static_cast<unsigned>(*MethodDecl->getReturnType()->getNullability(S.Context));
|
||||
auto nullabilityMethodImpl =
|
||||
*MethodImpl->getReturnType()->getNullability(S.Context);
|
||||
auto nullabilityMethodDecl =
|
||||
*MethodDecl->getReturnType()->getNullability(S.Context);
|
||||
S.Diag(MethodImpl->getLocation(),
|
||||
diag::warn_conflicting_nullability_attr_overriding_ret_types)
|
||||
<< unsNullabilityMethodImpl
|
||||
<< ((MethodImpl->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability) != 0)
|
||||
<< unsNullabilityMethodDecl
|
||||
<< ((MethodDecl->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability) != 0);
|
||||
<< DiagNullabilityKind(
|
||||
nullabilityMethodImpl,
|
||||
((MethodImpl->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability)
|
||||
!= 0))
|
||||
<< DiagNullabilityKind(
|
||||
nullabilityMethodDecl,
|
||||
((MethodDecl->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability)
|
||||
!= 0));
|
||||
S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration);
|
||||
}
|
||||
|
||||
|
@ -1486,15 +1490,17 @@ static bool CheckMethodOverrideParam(Sema &S,
|
|||
if (Warn && IsOverridingMode &&
|
||||
!isa<ObjCImplementationDecl>(MethodImpl->getDeclContext()) &&
|
||||
!S.Context.hasSameNullabilityTypeQualifier(ImplTy, IfaceTy, true)) {
|
||||
unsigned unsImplTy = static_cast<unsigned>(*ImplTy->getNullability(S.Context));
|
||||
unsigned unsIfaceTy = static_cast<unsigned>(*IfaceTy->getNullability(S.Context));
|
||||
S.Diag(ImplVar->getLocation(),
|
||||
diag::warn_conflicting_nullability_attr_overriding_param_types)
|
||||
<< unsImplTy
|
||||
<< ((ImplVar->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability) != 0)
|
||||
<< unsIfaceTy
|
||||
<< ((IfaceVar->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability) != 0);
|
||||
S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration);
|
||||
<< DiagNullabilityKind(
|
||||
*ImplTy->getNullability(S.Context),
|
||||
((ImplVar->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability)
|
||||
!= 0))
|
||||
<< DiagNullabilityKind(
|
||||
*IfaceTy->getNullability(S.Context),
|
||||
((IfaceVar->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability)
|
||||
!= 0));
|
||||
S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration);
|
||||
}
|
||||
if (S.Context.hasSameUnqualifiedType(ImplTy, IfaceTy))
|
||||
return true;
|
||||
|
@ -3184,8 +3190,8 @@ static QualType mergeTypeNullabilityForRedecl(Sema &S, SourceLocation loc,
|
|||
|
||||
// Complain about mismatched nullability.
|
||||
S.Diag(loc, diag::err_nullability_conflicting)
|
||||
<< static_cast<unsigned>(*nullability) << usesCSKeyword
|
||||
<< static_cast<unsigned>(*prevNullability) << prevUsesCSKeyword;
|
||||
<< DiagNullabilityKind(*nullability, usesCSKeyword)
|
||||
<< DiagNullabilityKind(*prevNullability, prevUsesCSKeyword);
|
||||
return type;
|
||||
}
|
||||
|
||||
|
|
|
@ -1758,7 +1758,7 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
|
|||
}
|
||||
}
|
||||
|
||||
void Sema::diagnoseNullResettableSynthesizedSetters(ObjCImplDecl *impDecl) {
|
||||
void Sema::diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl) {
|
||||
for (const auto *propertyImpl : impDecl->property_impls()) {
|
||||
const auto *property = propertyImpl->getPropertyDecl();
|
||||
|
||||
|
@ -2025,7 +2025,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
|
|||
if (property->getPropertyAttributes() &
|
||||
ObjCPropertyDecl::OBJC_PR_null_resettable) {
|
||||
QualType modifiedTy = resultTy;
|
||||
if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)){
|
||||
if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)) {
|
||||
if (*nullability == NullabilityKind::Unspecified)
|
||||
resultTy = Context.getAttributedType(AttributedType::attr_nonnull,
|
||||
modifiedTy, modifiedTy);
|
||||
|
|
|
@ -2567,19 +2567,19 @@ namespace {
|
|||
IdentifierInfo *Sema::getNullabilityKeyword(NullabilityKind nullability) {
|
||||
switch (nullability) {
|
||||
case NullabilityKind::NonNull:
|
||||
if (!Ident___nonnull)
|
||||
Ident___nonnull = PP.getIdentifierInfo("__nonnull");
|
||||
return Ident___nonnull;
|
||||
if (!Ident__Nonnull)
|
||||
Ident__Nonnull = PP.getIdentifierInfo("_Nonnull");
|
||||
return Ident__Nonnull;
|
||||
|
||||
case NullabilityKind::Nullable:
|
||||
if (!Ident___nullable)
|
||||
Ident___nullable = PP.getIdentifierInfo("__nullable");
|
||||
return Ident___nullable;
|
||||
if (!Ident__Nullable)
|
||||
Ident__Nullable = PP.getIdentifierInfo("_Nullable");
|
||||
return Ident__Nullable;
|
||||
|
||||
case NullabilityKind::Unspecified:
|
||||
if (!Ident___null_unspecified)
|
||||
Ident___null_unspecified = PP.getIdentifierInfo("__null_unspecified");
|
||||
return Ident___null_unspecified;
|
||||
if (!Ident__Null_unspecified)
|
||||
Ident__Null_unspecified = PP.getIdentifierInfo("_Null_unspecified");
|
||||
return Ident__Null_unspecified;
|
||||
}
|
||||
llvm_unreachable("Unknown nullability kind.");
|
||||
}
|
||||
|
@ -2900,7 +2900,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
|||
}
|
||||
}
|
||||
|
||||
// Determine whether we should infer __nonnull on pointer types.
|
||||
// Determine whether we should infer _Nonnull on pointer types.
|
||||
Optional<NullabilityKind> inferNullability;
|
||||
bool inferNullabilityCS = false;
|
||||
bool inferNullabilityInnerOnly = false;
|
||||
|
@ -3003,7 +3003,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
|||
break;
|
||||
|
||||
case PointerDeclaratorKind::SingleLevelPointer:
|
||||
// Infer __nonnull if we are in an assumes-nonnull region.
|
||||
// Infer _Nonnull if we are in an assumes-nonnull region.
|
||||
if (inAssumeNonNullRegion) {
|
||||
inferNullability = NullabilityKind::NonNull;
|
||||
inferNullabilityCS = (context == Declarator::ObjCParameterContext ||
|
||||
|
@ -3013,7 +3013,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
|||
|
||||
case PointerDeclaratorKind::CFErrorRefPointer:
|
||||
case PointerDeclaratorKind::NSErrorPointerPointer:
|
||||
// Within a function or method signature, infer __nullable at both
|
||||
// Within a function or method signature, infer _Nullable at both
|
||||
// levels.
|
||||
if (isFunctionOrMethod && inAssumeNonNullRegion)
|
||||
inferNullability = NullabilityKind::Nullable;
|
||||
|
@ -3023,7 +3023,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
|||
if (isFunctionOrMethod) {
|
||||
// On pointer-to-pointer parameters marked cf_returns_retained or
|
||||
// cf_returns_not_retained, if the outer pointer is explicit then
|
||||
// infer the inner pointer as __nullable.
|
||||
// infer the inner pointer as _Nullable.
|
||||
auto hasCFReturnsAttr = [](const AttributeList *NextAttr) -> bool {
|
||||
while (NextAttr) {
|
||||
if (NextAttr->getKind() == AttributeList::AT_CFReturnsRetained ||
|
||||
|
@ -3070,7 +3070,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
|||
}
|
||||
|
||||
// Local function that checks the nullability for a given pointer declarator.
|
||||
// Returns true if __nonnull was inferred.
|
||||
// Returns true if _Nonnull was inferred.
|
||||
auto inferPointerNullability = [&](SimplePointerKind pointerKind,
|
||||
SourceLocation pointerLoc,
|
||||
AttributeList *&attrs) -> AttributeList * {
|
||||
|
@ -5084,8 +5084,7 @@ bool Sema::checkNullabilityTypeSpecifier(QualType &type,
|
|||
// Duplicated nullability.
|
||||
if (nullability == *existingNullability) {
|
||||
Diag(nullabilityLoc, diag::warn_nullability_duplicate)
|
||||
<< static_cast<unsigned>(nullability)
|
||||
<< isContextSensitive
|
||||
<< DiagNullabilityKind(nullability, isContextSensitive)
|
||||
<< FixItHint::CreateRemoval(nullabilityLoc);
|
||||
|
||||
break;
|
||||
|
@ -5093,10 +5092,8 @@ bool Sema::checkNullabilityTypeSpecifier(QualType &type,
|
|||
|
||||
// Conflicting nullability.
|
||||
Diag(nullabilityLoc, diag::err_nullability_conflicting)
|
||||
<< static_cast<unsigned>(nullability)
|
||||
<< isContextSensitive
|
||||
<< static_cast<unsigned>(*existingNullability)
|
||||
<< false;
|
||||
<< DiagNullabilityKind(nullability, isContextSensitive)
|
||||
<< DiagNullabilityKind(*existingNullability, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5110,10 +5107,8 @@ bool Sema::checkNullabilityTypeSpecifier(QualType &type,
|
|||
if (auto existingNullability = desugared->getNullability(Context)) {
|
||||
if (nullability != *existingNullability) {
|
||||
Diag(nullabilityLoc, diag::err_nullability_conflicting)
|
||||
<< static_cast<unsigned>(nullability)
|
||||
<< isContextSensitive
|
||||
<< static_cast<unsigned>(*existingNullability)
|
||||
<< false;
|
||||
<< DiagNullabilityKind(nullability, isContextSensitive)
|
||||
<< DiagNullabilityKind(*existingNullability, false);
|
||||
|
||||
// Try to find the typedef with the existing nullability specifier.
|
||||
if (auto typedefType = desugared->getAs<TypedefType>()) {
|
||||
|
@ -5123,7 +5118,7 @@ bool Sema::checkNullabilityTypeSpecifier(QualType &type,
|
|||
= AttributedType::stripOuterNullability(underlyingType)) {
|
||||
if (*typedefNullability == *existingNullability) {
|
||||
Diag(typedefDecl->getLocation(), diag::note_nullability_here)
|
||||
<< static_cast<unsigned>(*existingNullability);
|
||||
<< DiagNullabilityKind(*existingNullability, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5135,7 +5130,7 @@ bool Sema::checkNullabilityTypeSpecifier(QualType &type,
|
|||
// If this definitely isn't a pointer type, reject the specifier.
|
||||
if (!desugared->canHaveNullability()) {
|
||||
Diag(nullabilityLoc, diag::err_nullability_nonpointer)
|
||||
<< static_cast<unsigned>(nullability) << isContextSensitive << type;
|
||||
<< DiagNullabilityKind(nullability, isContextSensitive) << type;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5148,10 +5143,10 @@ bool Sema::checkNullabilityTypeSpecifier(QualType &type,
|
|||
pointeeType->isObjCObjectPointerType() ||
|
||||
pointeeType->isMemberPointerType()) {
|
||||
Diag(nullabilityLoc, diag::err_nullability_cs_multilevel)
|
||||
<< static_cast<unsigned>(nullability)
|
||||
<< DiagNullabilityKind(nullability, true)
|
||||
<< type;
|
||||
Diag(nullabilityLoc, diag::note_nullability_type_specifier)
|
||||
<< static_cast<unsigned>(nullability)
|
||||
<< DiagNullabilityKind(nullability, false)
|
||||
<< type
|
||||
<< FixItHint::CreateReplacement(nullabilityLoc,
|
||||
getNullabilitySpelling(nullability));
|
||||
|
@ -5216,7 +5211,8 @@ static bool distributeNullabilityTypeAttr(TypeProcessingState &state,
|
|||
|
||||
auto diag = state.getSema().Diag(attr.getLoc(),
|
||||
diag::warn_nullability_declspec)
|
||||
<< static_cast<unsigned>(mapNullabilityAttrKind(attr.getKind()))
|
||||
<< DiagNullabilityKind(mapNullabilityAttrKind(attr.getKind()),
|
||||
attr.isContextSensitiveKeywordAttribute())
|
||||
<< type
|
||||
<< static_cast<unsigned>(pointerKind);
|
||||
|
||||
|
|
|
@ -5405,7 +5405,7 @@ QualType TreeTransform<Derived>::TransformAttributedType(
|
|||
if (auto nullability = oldType->getImmediateNullability()) {
|
||||
if (!modifiedType->canHaveNullability()) {
|
||||
SemaRef.Diag(TL.getAttrNameLoc(), diag::err_nullability_nonpointer)
|
||||
<< static_cast<unsigned>(*nullability) << false << modifiedType;
|
||||
<< DiagNullabilityKind(*nullability, false) << modifiedType;
|
||||
return QualType();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2165,7 +2165,7 @@ void testCFReturnsNotRetained() {
|
|||
}
|
||||
|
||||
void testCFReturnsNotRetainedAnnotated() {
|
||||
extern void getViaParam2(CFTypeRef * __nonnull CF_RETURNS_NOT_RETAINED outObj);
|
||||
extern void getViaParam2(CFTypeRef * _Nonnull CF_RETURNS_NOT_RETAINED outObj);
|
||||
CFTypeRef obj;
|
||||
getViaParam2(&obj);
|
||||
CFRelease(obj); // // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
// RUN: not %clang_cc1 -fixit -fblocks -Werror=nullability-declspec -x c++ %t
|
||||
// RUN: %clang_cc1 -fblocks -Werror=nullability-declspec -x c++ %t
|
||||
|
||||
__nullable int *ip1; // expected-error{{nullability specifier '__nullable' cannot be applied to non-pointer type 'int'; did you mean to apply the specifier to the pointer?}}
|
||||
__nullable int (*fp1)(int); // expected-error{{nullability specifier '__nullable' cannot be applied to non-pointer type 'int'; did you mean to apply the specifier to the function pointer?}}
|
||||
__nonnull int (^bp1)(int); // expected-error{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'int'; did you mean to apply the specifier to the block pointer?}}
|
||||
_Nullable int *ip1; // expected-error{{nullability specifier '_Nullable' cannot be applied to non-pointer type 'int'; did you mean to apply the specifier to the pointer?}}
|
||||
_Nullable int (*fp1)(int); // expected-error{{nullability specifier '_Nullable' cannot be applied to non-pointer type 'int'; did you mean to apply the specifier to the function pointer?}}
|
||||
_Nonnull int (^bp1)(int); // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'int'; did you mean to apply the specifier to the block pointer?}}
|
||||
|
|
|
@ -345,4 +345,4 @@ void test_Nullability(Nullability *n, A* a) {
|
|||
// CHECK-DISTRIB-OBJECTS: ObjCInstanceMethodDecl:{ResultType void}{TypedText method:}{Placeholder (in bycopy A *)}{HorizontalSpace }{TypedText result:}{Placeholder (out byref A **)} (35)
|
||||
|
||||
// RUN: c-index-test -code-completion-at=%s:197:6 %s | FileCheck -check-prefix=CHECK-NULLABLE %s
|
||||
// CHECK-NULLABLE: ObjCInstanceMethodDecl:{ResultType A * __nonnull}{TypedText method:}{Placeholder (nullable A *)}
|
||||
// CHECK-NULLABLE: ObjCInstanceMethodDecl:{ResultType A * _Nonnull}{TypedText method:}{Placeholder (nullable A *)}
|
||||
|
|
|
@ -16,8 +16,8 @@ void f(int x) {
|
|||
// CHECK-IF-ELSE-SIMPLE: NotImplemented:{TypedText else}{HorizontalSpace }{Text if}{HorizontalSpace }{LeftParen (}{Placeholder expression}{RightParen )} (40)
|
||||
|
||||
// RUN: c-index-test -code-completion-at=%s:6:1 %s | FileCheck -check-prefix=CHECK-STMT %s
|
||||
// CHECK-STMT: NotImplemented:{TypedText __nonnull} (50)
|
||||
// CHECK-STMT: NotImplemented:{TypedText __nullable} (50)
|
||||
// CHECK-STMT: NotImplemented:{TypedText _Nonnull} (50)
|
||||
// CHECK-STMT: NotImplemented:{TypedText _Nullable} (50)
|
||||
// CHECK-STMT: NotImplemented:{TypedText char} (50)
|
||||
// CHECK-STMT: NotImplemented:{TypedText const} (50)
|
||||
// CHECK-STMT: NotImplemented:{TypedText double} (50)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -std=c99 -Wno-nullability-declspec -pedantic %s -verify
|
||||
|
||||
__nonnull int *ptr; // expected-warning{{type nullability specifier '__nonnull' is a Clang extension}}
|
||||
_Nonnull int *ptr; // expected-warning{{type nullability specifier '_Nonnull' is a Clang extension}}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnullability-extension"
|
||||
__nonnull int *ptr2; // no-warning
|
||||
_Nonnull int *ptr2; // no-warning
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
#if __has_feature(nullability)
|
||||
|
|
|
@ -7,29 +7,29 @@
|
|||
#endif
|
||||
|
||||
|
||||
int * __nullable foo(int * __nonnull x);
|
||||
int * _Nullable foo(int * _Nonnull x);
|
||||
|
||||
int *__nonnull ret_nonnull();
|
||||
int *_Nonnull ret_nonnull();
|
||||
|
||||
int *foo(int *x) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int * __nullable foo1(int * __nonnull x); // expected-note {{previous declaration is here}}
|
||||
int * _Nullable foo1(int * _Nonnull x); // expected-note {{previous declaration is here}}
|
||||
|
||||
int *foo1(int * __nullable x) { // expected-warning {{nullability specifier '__nullable' conflicts with existing specifier '__nonnull'}}
|
||||
int *foo1(int * _Nullable x) { // expected-warning {{nullability specifier '_Nullable' conflicts with existing specifier '_Nonnull'}}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int * __nullable foo2(int * __nonnull x);
|
||||
int * _Nullable foo2(int * _Nonnull x);
|
||||
|
||||
int *foo2(int * __nonnull x) {
|
||||
int *foo2(int * _Nonnull x) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int * __nullable foo3(int * __nullable x); // expected-note {{previous declaration is here}}
|
||||
int * _Nullable foo3(int * _Nullable x); // expected-note {{previous declaration is here}}
|
||||
|
||||
int *foo3(int * __nonnull x) { // expected-warning {{nullability specifier '__nonnull' conflicts with existing specifier '__nullable'}}
|
||||
int *foo3(int * _Nonnull x) { // expected-warning {{nullability specifier '_Nonnull' conflicts with existing specifier '_Nullable'}}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,88 +8,88 @@
|
|||
typedef int * int_ptr;
|
||||
|
||||
// Parse nullability type specifiers.
|
||||
typedef int * __nonnull nonnull_int_ptr; // expected-note{{'__nonnull' specified here}}
|
||||
typedef int * __nullable nullable_int_ptr;
|
||||
typedef int * __null_unspecified null_unspecified_int_ptr;
|
||||
typedef int * _Nonnull nonnull_int_ptr; // expected-note{{'_Nonnull' specified here}}
|
||||
typedef int * _Nullable nullable_int_ptr;
|
||||
typedef int * _Null_unspecified null_unspecified_int_ptr;
|
||||
|
||||
// Redundant nullability type specifiers.
|
||||
typedef int * __nonnull __nonnull redundant_1; // expected-warning{{duplicate nullability specifier '__nonnull'}}
|
||||
typedef int * _Nonnull _Nonnull redundant_1; // expected-warning{{duplicate nullability specifier '_Nonnull'}}
|
||||
|
||||
// Conflicting nullability type specifiers.
|
||||
typedef int * __nonnull __nullable conflicting_1; // expected-error{{nullability specifier '__nonnull' conflicts with existing specifier '__nullable'}}
|
||||
typedef int * __null_unspecified __nonnull conflicting_2; // expected-error{{nullability specifier '__null_unspecified' conflicts with existing specifier '__nonnull'}}
|
||||
typedef int * _Nonnull _Nullable conflicting_1; // expected-error{{nullability specifier '_Nonnull' conflicts with existing specifier '_Nullable'}}
|
||||
typedef int * _Null_unspecified _Nonnull conflicting_2; // expected-error{{nullability specifier '_Null_unspecified' conflicts with existing specifier '_Nonnull'}}
|
||||
|
||||
// Redundant nullability specifiers via a typedef are okay.
|
||||
typedef nonnull_int_ptr __nonnull redundant_okay_1;
|
||||
typedef nonnull_int_ptr _Nonnull redundant_okay_1;
|
||||
|
||||
// Conflicting nullability specifiers via a typedef are not.
|
||||
typedef nonnull_int_ptr __nullable conflicting_2; // expected-error{{nullability specifier '__nullable' conflicts with existing specifier '__nonnull'}}
|
||||
typedef nonnull_int_ptr _Nullable conflicting_2; // expected-error{{nullability specifier '_Nullable' conflicts with existing specifier '_Nonnull'}}
|
||||
typedef nonnull_int_ptr nonnull_int_ptr_typedef;
|
||||
typedef nonnull_int_ptr_typedef __nullable conflicting_2; // expected-error{{nullability specifier '__nullable' conflicts with existing specifier '__nonnull'}}
|
||||
typedef nonnull_int_ptr_typedef _Nullable conflicting_2; // expected-error{{nullability specifier '_Nullable' conflicts with existing specifier '_Nonnull'}}
|
||||
typedef nonnull_int_ptr_typedef nonnull_int_ptr_typedef_typedef;
|
||||
typedef nonnull_int_ptr_typedef_typedef __null_unspecified conflicting_3; // expected-error{{nullability specifier '__null_unspecified' conflicts with existing specifier '__nonnull'}}
|
||||
typedef nonnull_int_ptr_typedef_typedef _Null_unspecified conflicting_3; // expected-error{{nullability specifier '_Null_unspecified' conflicts with existing specifier '_Nonnull'}}
|
||||
|
||||
// Nullability applies to all pointer types.
|
||||
typedef int (* __nonnull function_pointer_type_1)(int, int);
|
||||
typedef int (^ __nonnull block_type_1)(int, int);
|
||||
typedef int (* _Nonnull function_pointer_type_1)(int, int);
|
||||
typedef int (^ _Nonnull block_type_1)(int, int);
|
||||
|
||||
// Nullability must be on a pointer type.
|
||||
typedef int __nonnull int_type_1; // expected-error{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'int'}}
|
||||
typedef int _Nonnull int_type_1; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'int'}}
|
||||
|
||||
// Nullability can move out to a pointer/block pointer declarator
|
||||
// (with a suppressed warning).
|
||||
typedef __nonnull int * nonnull_int_ptr_2;
|
||||
typedef int __nullable * nullable_int_ptr_2;
|
||||
typedef __nonnull int (* function_pointer_type_2)(int, int);
|
||||
typedef __nonnull int (^ block_type_2)(int, int);
|
||||
typedef __nonnull int * * __nullable nonnull_int_ptr_ptr_1;
|
||||
typedef __nonnull int *(^ block_type_3)(int, int);
|
||||
typedef __nonnull int *(* function_pointer_type_3)(int, int);
|
||||
typedef __nonnull int_ptr (^ block_type_4)(int, int);
|
||||
typedef __nonnull int_ptr (* function_pointer_type_4)(int, int);
|
||||
typedef _Nonnull int * nonnull_int_ptr_2;
|
||||
typedef int _Nullable * nullable_int_ptr_2;
|
||||
typedef _Nonnull int (* function_pointer_type_2)(int, int);
|
||||
typedef _Nonnull int (^ block_type_2)(int, int);
|
||||
typedef _Nonnull int * * _Nullable nonnull_int_ptr_ptr_1;
|
||||
typedef _Nonnull int *(^ block_type_3)(int, int);
|
||||
typedef _Nonnull int *(* function_pointer_type_3)(int, int);
|
||||
typedef _Nonnull int_ptr (^ block_type_4)(int, int);
|
||||
typedef _Nonnull int_ptr (* function_pointer_type_4)(int, int);
|
||||
|
||||
void acceptFunctionPtr(__nonnull int *(*)(void));
|
||||
void acceptBlockPtr(__nonnull int *(^)(void));
|
||||
void acceptFunctionPtr(_Nonnull int *(*)(void));
|
||||
void acceptBlockPtr(_Nonnull int *(^)(void));
|
||||
|
||||
void testBlockFunctionPtrNullability() {
|
||||
float *fp;
|
||||
fp = (function_pointer_type_3)0; // expected-warning{{from 'function_pointer_type_3' (aka 'int * __nonnull (*)(int, int)')}}
|
||||
fp = (block_type_3)0; // expected-error{{from incompatible type 'block_type_3' (aka 'int * __nonnull (^)(int, int)')}}
|
||||
fp = (function_pointer_type_4)0; // expected-warning{{from 'function_pointer_type_4' (aka 'int_ptr __nonnull (*)(int, int)')}}
|
||||
fp = (block_type_4)0; // expected-error{{from incompatible type 'block_type_4' (aka 'int_ptr __nonnull (^)(int, int)')}}
|
||||
fp = (function_pointer_type_3)0; // expected-warning{{from 'function_pointer_type_3' (aka 'int * _Nonnull (*)(int, int)')}}
|
||||
fp = (block_type_3)0; // expected-error{{from incompatible type 'block_type_3' (aka 'int * _Nonnull (^)(int, int)')}}
|
||||
fp = (function_pointer_type_4)0; // expected-warning{{from 'function_pointer_type_4' (aka 'int_ptr _Nonnull (*)(int, int)')}}
|
||||
fp = (block_type_4)0; // expected-error{{from incompatible type 'block_type_4' (aka 'int_ptr _Nonnull (^)(int, int)')}}
|
||||
|
||||
acceptFunctionPtr(0); // no-warning
|
||||
acceptBlockPtr(0); // no-warning
|
||||
}
|
||||
|
||||
// Moving nullability where it creates a conflict.
|
||||
typedef __nonnull int * __nullable * conflict_int_ptr_ptr_2; // expected-error{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'int'}}
|
||||
typedef _Nonnull int * _Nullable * conflict_int_ptr_ptr_2; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'int'}}
|
||||
|
||||
// Nullability is not part of the canonical type.
|
||||
typedef int * __nonnull ambiguous_int_ptr;
|
||||
typedef int * _Nonnull ambiguous_int_ptr;
|
||||
typedef int * ambiguous_int_ptr;
|
||||
typedef int * __nullable ambiguous_int_ptr;
|
||||
typedef int * _Nullable ambiguous_int_ptr;
|
||||
|
||||
// Printing of nullability.
|
||||
float f;
|
||||
int * __nonnull ip_1 = &f; // expected-warning{{incompatible pointer types initializing 'int * __nonnull' with an expression of type 'float *'}}
|
||||
int * _Nonnull ip_1 = &f; // expected-warning{{incompatible pointer types initializing 'int * _Nonnull' with an expression of type 'float *'}}
|
||||
|
||||
// Check printing of nullability specifiers.
|
||||
void printing_nullability(void) {
|
||||
int * __nonnull iptr;
|
||||
float *fptr = iptr; // expected-warning{{incompatible pointer types initializing 'float *' with an expression of type 'int * __nonnull'}}
|
||||
int * _Nonnull iptr;
|
||||
float *fptr = iptr; // expected-warning{{incompatible pointer types initializing 'float *' with an expression of type 'int * _Nonnull'}}
|
||||
|
||||
int * * __nonnull iptrptr;
|
||||
float **fptrptr = iptrptr; // expected-warning{{incompatible pointer types initializing 'float **' with an expression of type 'int ** __nonnull'}}
|
||||
int * * _Nonnull iptrptr;
|
||||
float **fptrptr = iptrptr; // expected-warning{{incompatible pointer types initializing 'float **' with an expression of type 'int ** _Nonnull'}}
|
||||
|
||||
int * __nullable * __nonnull iptrptr2;
|
||||
float * *fptrptr2 = iptrptr2; // expected-warning{{incompatible pointer types initializing 'float **' with an expression of type 'int * __nullable * __nonnull'}}
|
||||
int * _Nullable * _Nonnull iptrptr2;
|
||||
float * *fptrptr2 = iptrptr2; // expected-warning{{incompatible pointer types initializing 'float **' with an expression of type 'int * _Nullable * _Nonnull'}}
|
||||
}
|
||||
|
||||
// Check passing null to a __nonnull argument.
|
||||
void accepts_nonnull_1(__nonnull int *ptr);
|
||||
void (*accepts_nonnull_2)(__nonnull int *ptr);
|
||||
void (^accepts_nonnull_3)(__nonnull int *ptr);
|
||||
// Check passing null to a _Nonnull argument.
|
||||
void accepts_nonnull_1(_Nonnull int *ptr);
|
||||
void (*accepts_nonnull_2)(_Nonnull int *ptr);
|
||||
void (^accepts_nonnull_3)(_Nonnull int *ptr);
|
||||
|
||||
void test_accepts_nonnull_null_pointer_literal() {
|
||||
accepts_nonnull_1(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
|
||||
|
@ -97,17 +97,17 @@ void test_accepts_nonnull_null_pointer_literal() {
|
|||
accepts_nonnull_3(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
|
||||
}
|
||||
|
||||
// Check returning nil from a __nonnull-returning function.
|
||||
__nonnull int *returns_int_ptr(int x) {
|
||||
// Check returning nil from a _Nonnull-returning function.
|
||||
_Nonnull int *returns_int_ptr(int x) {
|
||||
if (x) {
|
||||
return 0; // expected-warning{{null returned from function that requires a non-null return value}}
|
||||
}
|
||||
|
||||
return (__nonnull int *)0;
|
||||
return (_Nonnull int *)0;
|
||||
}
|
||||
|
||||
// Check nullable-to-nonnull conversions.
|
||||
void nullable_to_nonnull(__nullable int *ptr) {
|
||||
void nullable_to_nonnull(_Nullable int *ptr) {
|
||||
int *a = ptr; // okay
|
||||
__nonnull int *b = ptr; // expected-warning{{implicit conversion from nullable pointer 'int * __nullable' to non-nullable pointer type 'int * __nonnull'}}
|
||||
_Nonnull int *b = ptr; // expected-warning{{implicit conversion from nullable pointer 'int * _Nullable' to non-nullable pointer type 'int * _Nonnull'}}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
struct X { };
|
||||
|
||||
__nullable int *ip1; // expected-error{{nullability specifier '__nullable' cannot be applied to non-pointer type 'int'; did you mean to apply the specifier to the pointer?}}
|
||||
__nullable int (*fp1)(int); // expected-error{{nullability specifier '__nullable' cannot be applied to non-pointer type 'int'; did you mean to apply the specifier to the function pointer?}}
|
||||
__nonnull int (^bp1)(int); // expected-error{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'int'; did you mean to apply the specifier to the block pointer?}}
|
||||
__nonnull int X::*pmd1; // expected-error{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'int'; did you mean to apply the specifier to the member pointer?}}
|
||||
__nonnull int (X::*pmf1)(int); // expected-error{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'int'; did you mean to apply the specifier to the member function pointer?}}
|
||||
_Nullable int *ip1; // expected-error{{nullability specifier '_Nullable' cannot be applied to non-pointer type 'int'; did you mean to apply the specifier to the pointer?}}
|
||||
_Nullable int (*fp1)(int); // expected-error{{nullability specifier '_Nullable' cannot be applied to non-pointer type 'int'; did you mean to apply the specifier to the function pointer?}}
|
||||
_Nonnull int (^bp1)(int); // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'int'; did you mean to apply the specifier to the block pointer?}}
|
||||
_Nonnull int X::*pmd1; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'int'; did you mean to apply the specifier to the member pointer?}}
|
||||
_Nonnull int (X::*pmf1)(int); // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'int'; did you mean to apply the specifier to the member function pointer?}}
|
||||
|
|
|
@ -6,24 +6,24 @@ class X {
|
|||
};
|
||||
|
||||
// Nullability applies to all pointer types.
|
||||
typedef int (X::* __nonnull member_function_type_1)(int);
|
||||
typedef int X::* __nonnull member_data_type_1;
|
||||
typedef nullptr_t __nonnull nonnull_nullptr_t; // expected-error{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'nullptr_t'}}
|
||||
typedef int (X::* _Nonnull member_function_type_1)(int);
|
||||
typedef int X::* _Nonnull member_data_type_1;
|
||||
typedef nullptr_t _Nonnull nonnull_nullptr_t; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'nullptr_t'}}
|
||||
|
||||
// Nullability can move into member pointers (this is suppressing a warning).
|
||||
typedef __nonnull int (X::* member_function_type_2)(int);
|
||||
typedef int (X::* __nonnull member_function_type_3)(int);
|
||||
typedef __nonnull int X::* member_data_type_2;
|
||||
typedef _Nonnull int (X::* member_function_type_2)(int);
|
||||
typedef int (X::* _Nonnull member_function_type_3)(int);
|
||||
typedef _Nonnull int X::* member_data_type_2;
|
||||
|
||||
// Adding non-null via a template.
|
||||
template<typename T>
|
||||
struct AddNonNull {
|
||||
typedef __nonnull T type; // expected-error{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'int'}}
|
||||
// expected-error@-1{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'nullptr_t'}}
|
||||
typedef _Nonnull T type; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'int'}}
|
||||
// expected-error@-1{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'nullptr_t'}}
|
||||
};
|
||||
|
||||
typedef AddNonNull<int *>::type nonnull_int_ptr_1;
|
||||
typedef AddNonNull<int * __nullable>::type nonnull_int_ptr_2; // FIXME: check that it was overridden
|
||||
typedef AddNonNull<int * _Nullable>::type nonnull_int_ptr_2; // FIXME: check that it was overridden
|
||||
typedef AddNonNull<nullptr_t>::type nonnull_int_ptr_3; // expected-note{{in instantiation of template class}}
|
||||
|
||||
typedef AddNonNull<int>::type nonnull_non_pointer_1; // expected-note{{in instantiation of template class 'AddNonNull<int>' requested here}}
|
||||
|
@ -31,22 +31,22 @@ typedef AddNonNull<int>::type nonnull_non_pointer_1; // expected-note{{in instan
|
|||
// Non-null checking within a template.
|
||||
template<typename T>
|
||||
struct AddNonNull2 {
|
||||
typedef __nonnull AddNonNull<T> invalid1; // expected-error{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'AddNonNull<T>'}}
|
||||
typedef __nonnull AddNonNull2 invalid2; // expected-error{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'AddNonNull2<T>'}}
|
||||
typedef __nonnull AddNonNull2<T> invalid3; // expected-error{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'AddNonNull2<T>'}}
|
||||
typedef __nonnull typename AddNonNull<T>::type okay1;
|
||||
typedef _Nonnull AddNonNull<T> invalid1; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'AddNonNull<T>'}}
|
||||
typedef _Nonnull AddNonNull2 invalid2; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'AddNonNull2<T>'}}
|
||||
typedef _Nonnull AddNonNull2<T> invalid3; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'AddNonNull2<T>'}}
|
||||
typedef _Nonnull typename AddNonNull<T>::type okay1;
|
||||
|
||||
// Don't move past a dependent type even if we know that nullability
|
||||
// cannot apply to that specific dependent type.
|
||||
typedef __nonnull AddNonNull<T> (*invalid4); // expected-error{{nullability specifier '__nonnull' cannot be applied to non-pointer type 'AddNonNull<T>'}}
|
||||
typedef _Nonnull AddNonNull<T> (*invalid4); // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'AddNonNull<T>'}}
|
||||
};
|
||||
|
||||
// Check passing null to a __nonnull argument.
|
||||
void (*accepts_nonnull_1)(__nonnull int *ptr);
|
||||
void (*& accepts_nonnull_2)(__nonnull int *ptr) = accepts_nonnull_1;
|
||||
void (X::* accepts_nonnull_3)(__nonnull int *ptr);
|
||||
void accepts_nonnull_4(__nonnull int *ptr);
|
||||
void (&accepts_nonnull_5)(__nonnull int *ptr) = accepts_nonnull_4;
|
||||
// Check passing null to a _Nonnull argument.
|
||||
void (*accepts_nonnull_1)(_Nonnull int *ptr);
|
||||
void (*& accepts_nonnull_2)(_Nonnull int *ptr) = accepts_nonnull_1;
|
||||
void (X::* accepts_nonnull_3)(_Nonnull int *ptr);
|
||||
void accepts_nonnull_4(_Nonnull int *ptr);
|
||||
void (&accepts_nonnull_5)(_Nonnull int *ptr) = accepts_nonnull_4;
|
||||
|
||||
void test_accepts_nonnull_null_pointer_literal(X *x) {
|
||||
accepts_nonnull_1(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
|
||||
|
@ -56,7 +56,7 @@ void test_accepts_nonnull_null_pointer_literal(X *x) {
|
|||
accepts_nonnull_5(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
|
||||
}
|
||||
|
||||
template<void FP(__nonnull int*)>
|
||||
template<void FP(_Nonnull int*)>
|
||||
void test_accepts_nonnull_null_pointer_literal_template() {
|
||||
FP(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ __attribute__((objc_arc_weak_reference_unavailable))
|
|||
@interface I
|
||||
{
|
||||
}
|
||||
@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont * __nullable', which does not support weak references}}
|
||||
@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont * _Nullable', which does not support weak references}}
|
||||
@end
|
||||
|
||||
@implementation I // expected-note {{when implemented by class I}}
|
||||
|
@ -65,7 +65,7 @@ __attribute__((objc_arc_weak_reference_unavailable))
|
|||
|
||||
// rdar://13676793
|
||||
@protocol MyProtocol
|
||||
@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont * __nullable', which does not support weak references}}
|
||||
@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont * _Nullable', which does not support weak references}}
|
||||
@end
|
||||
|
||||
@interface I1 <MyProtocol>
|
||||
|
@ -76,7 +76,7 @@ __attribute__((objc_arc_weak_reference_unavailable))
|
|||
@end
|
||||
|
||||
@interface Super
|
||||
@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont * __nullable', which does not support weak references}}
|
||||
@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont * _Nullable', which does not support weak references}}
|
||||
@end
|
||||
|
||||
|
||||
|
|
|
@ -5,6 +5,6 @@ __attribute__((objc_root_class))
|
|||
@end
|
||||
|
||||
// ARC qualifiers stacked with nullability.
|
||||
void accepts_arc_qualified(NSFoo * __unsafe_unretained __nonnull obj) {
|
||||
void accepts_arc_qualified(NSFoo * __unsafe_unretained _Nonnull obj) {
|
||||
accepts_arc_qualified(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
|
||||
}
|
||||
|
|
|
@ -2,29 +2,29 @@
|
|||
|
||||
__attribute__((objc_root_class))
|
||||
@interface NSFoo
|
||||
- (void)methodTakingIntPtr:(__nonnull int *)ptr;
|
||||
- (__nonnull int *)methodReturningIntPtr;
|
||||
- (void)methodTakingIntPtr:(_Nonnull int *)ptr;
|
||||
- (_Nonnull int *)methodReturningIntPtr;
|
||||
@end
|
||||
|
||||
// Nullability applies to all pointer types.
|
||||
typedef NSFoo * __nonnull nonnull_NSFoo_ptr;
|
||||
typedef id __nonnull nonnull_id;
|
||||
typedef SEL __nonnull nonnull_SEL;
|
||||
typedef NSFoo * _Nonnull nonnull_NSFoo_ptr;
|
||||
typedef id _Nonnull nonnull_id;
|
||||
typedef SEL _Nonnull nonnull_SEL;
|
||||
|
||||
// Nullability can move into Objective-C pointer types.
|
||||
typedef __nonnull NSFoo * nonnull_NSFoo_ptr_2;
|
||||
typedef _Nonnull NSFoo * nonnull_NSFoo_ptr_2;
|
||||
|
||||
// Conflicts from nullability moving into Objective-C pointer type.
|
||||
typedef __nonnull NSFoo * __nullable conflict_NSFoo_ptr_2; // expected-error{{'__nonnull' cannot be applied to non-pointer type 'NSFoo'}}
|
||||
typedef _Nonnull NSFoo * _Nullable conflict_NSFoo_ptr_2; // expected-error{{'_Nonnull' cannot be applied to non-pointer type 'NSFoo'}}
|
||||
|
||||
void testBlocksPrinting(NSFoo * __nullable (^bp)(int)) {
|
||||
int *ip = bp; // expected-error{{'NSFoo * __nullable (^)(int)'}}
|
||||
void testBlocksPrinting(NSFoo * _Nullable (^bp)(int)) {
|
||||
int *ip = bp; // expected-error{{'NSFoo * _Nullable (^)(int)'}}
|
||||
}
|
||||
|
||||
// Check returning nil from a __nonnull-returning method.
|
||||
// Check returning nil from a _Nonnull-returning method.
|
||||
@implementation NSFoo
|
||||
- (void)methodTakingIntPtr:(__nonnull int *)ptr { }
|
||||
- (__nonnull int *)methodReturningIntPtr {
|
||||
- (void)methodTakingIntPtr:(_Nonnull int *)ptr { }
|
||||
- (_Nonnull int *)methodReturningIntPtr {
|
||||
return 0; // no warning
|
||||
}
|
||||
@end
|
||||
|
@ -35,15 +35,15 @@ __attribute__((objc_root_class))
|
|||
- (nonnull NSFoo *)methodWithFoo:(nonnull NSFoo *)foo;
|
||||
|
||||
- (nonnull NSFoo **)invalidMethod1; // expected-error{{nullability keyword 'nonnull' cannot be applied to multi-level pointer type 'NSFoo **'}}
|
||||
// expected-note@-1{{use nullability type specifier '__nonnull' to affect the innermost pointer type of 'NSFoo **'}}
|
||||
- (nonnull NSFoo * __nullable)conflictingMethod1; // expected-error{{nullability specifier '__nullable' conflicts with existing specifier '__nonnull'}}
|
||||
- (nonnull NSFoo * __nonnull)redundantMethod1; // expected-warning{{duplicate nullability specifier '__nonnull'}}
|
||||
// expected-note@-1{{use nullability type specifier '_Nonnull' to affect the innermost pointer type of 'NSFoo **'}}
|
||||
- (nonnull NSFoo * _Nullable)conflictingMethod1; // expected-error{{nullability specifier '_Nullable' conflicts with existing specifier '_Nonnull'}}
|
||||
- (nonnull NSFoo * _Nonnull)redundantMethod1; // expected-warning{{duplicate nullability specifier '_Nonnull'}}
|
||||
|
||||
@property(nonnull,retain) NSFoo *property1;
|
||||
@property(nullable,assign) NSFoo ** invalidProperty1; // expected-error{{nullability keyword 'nullable' cannot be applied to multi-level pointer type 'NSFoo **'}}
|
||||
// expected-note@-1{{use nullability type specifier '__nullable' to affect the innermost pointer type of 'NSFoo **'}}
|
||||
@property(null_unspecified,retain) NSFoo * __nullable conflictingProperty1; // expected-error{{nullability specifier '__nullable' conflicts with existing specifier '__null_unspecified'}}
|
||||
@property(retain,nonnull) NSFoo * __nonnull redundantProperty1; // expected-warning{{duplicate nullability specifier '__nonnull'}}
|
||||
// expected-note@-1{{use nullability type specifier '_Nullable' to affect the innermost pointer type of 'NSFoo **'}}
|
||||
@property(null_unspecified,retain) NSFoo * _Nullable conflictingProperty1; // expected-error{{nullability specifier '_Nullable' conflicts with existing specifier '_Null_unspecified'}}
|
||||
@property(retain,nonnull) NSFoo * _Nonnull redundantProperty1; // expected-warning{{duplicate nullability specifier '_Nonnull'}}
|
||||
|
||||
@property(null_unspecified,retain,nullable) NSFoo *conflictingProperty3; // expected-error{{nullability specifier 'nullable' conflicts with existing specifier 'null_unspecified'}}
|
||||
@property(nullable,retain,nullable) NSFoo *redundantProperty3; // expected-warning{{duplicate nullability specifier 'nullable'}}
|
||||
|
@ -52,19 +52,19 @@ __attribute__((objc_root_class))
|
|||
@interface NSBar ()
|
||||
@property(nonnull,retain) NSFoo *property2;
|
||||
@property(nullable,assign) NSFoo ** invalidProperty2; // expected-error{{nullability keyword 'nullable' cannot be applied to multi-level pointer type 'NSFoo **'}}
|
||||
// expected-note@-1{{use nullability type specifier '__nullable' to affect the innermost pointer type of 'NSFoo **'}}
|
||||
@property(null_unspecified,retain) NSFoo * __nullable conflictingProperty2; // expected-error{{nullability specifier '__nullable' conflicts with existing specifier '__null_unspecified'}}
|
||||
@property(retain,nonnull) NSFoo * __nonnull redundantProperty2; // expected-warning{{duplicate nullability specifier '__nonnull'}}
|
||||
// expected-note@-1{{use nullability type specifier '_Nullable' to affect the innermost pointer type of 'NSFoo **'}}
|
||||
@property(null_unspecified,retain) NSFoo * _Nullable conflictingProperty2; // expected-error{{nullability specifier '_Nullable' conflicts with existing specifier '_Null_unspecified'}}
|
||||
@property(retain,nonnull) NSFoo * _Nonnull redundantProperty2; // expected-warning{{duplicate nullability specifier '_Nonnull'}}
|
||||
@end
|
||||
|
||||
void test_accepts_nonnull_null_pointer_literal(NSFoo *foo, __nonnull NSBar *bar) {
|
||||
void test_accepts_nonnull_null_pointer_literal(NSFoo *foo, _Nonnull NSBar *bar) {
|
||||
[foo methodTakingIntPtr: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
|
||||
[bar methodWithFoo: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
|
||||
bar.property1 = 0; // expected-warning{{null passed to a callee that requires a non-null argument}}
|
||||
bar.property2 = 0; // expected-warning{{null passed to a callee that requires a non-null argument}}
|
||||
[bar setProperty1: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
|
||||
[bar setProperty2: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
|
||||
int *ptr = bar.property1; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'NSFoo * __nonnull'}}
|
||||
int *ptr = bar.property1; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'NSFoo * _Nonnull'}}
|
||||
}
|
||||
|
||||
// Check returning nil from a nonnull-returning method.
|
||||
|
@ -82,7 +82,7 @@ void test_accepts_nonnull_null_pointer_literal(NSFoo *foo, __nonnull NSBar *bar)
|
|||
}
|
||||
- (NSFoo *)redundantMethod1 {
|
||||
int *ip = 0;
|
||||
return ip; // expected-warning{{result type 'NSFoo * __nonnull'}}
|
||||
return ip; // expected-warning{{result type 'NSFoo * _Nonnull'}}
|
||||
}
|
||||
@end
|
||||
|
||||
|
@ -95,8 +95,8 @@ __attribute__((objc_root_class))
|
|||
|
||||
@implementation NSMerge
|
||||
- (NSFoo *)methodA:(NSFoo*)foo {
|
||||
int *ptr = foo; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'NSFoo * __nonnull'}}
|
||||
return ptr; // expected-warning{{result type 'NSFoo * __nonnull'}}
|
||||
int *ptr = foo; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'NSFoo * _Nonnull'}}
|
||||
return ptr; // expected-warning{{result type 'NSFoo * _Nonnull'}}
|
||||
}
|
||||
|
||||
- (nullable NSFoo *)methodB:(null_unspecified NSFoo*)foo { // expected-error{{nullability specifier 'nullable' conflicts with existing specifier 'nonnull'}} \
|
||||
|
@ -106,7 +106,7 @@ __attribute__((objc_root_class))
|
|||
|
||||
- (nonnull NSFoo *)methodC:(nullable NSFoo*)foo {
|
||||
int *ip = 0;
|
||||
return ip; // expected-warning{{result type 'NSFoo * __nonnull'}}
|
||||
return ip; // expected-warning{{result type 'NSFoo * _Nonnull'}}
|
||||
}
|
||||
@end
|
||||
|
||||
|
@ -119,27 +119,27 @@ __attribute__((objc_root_class))
|
|||
@end
|
||||
|
||||
void test_receiver_merge(NSMergeReceiver *none,
|
||||
__nonnull NSMergeReceiver *nonnull,
|
||||
__nullable NSMergeReceiver *nullable,
|
||||
__null_unspecified NSMergeReceiver *null_unspecified) {
|
||||
_Nonnull NSMergeReceiver *nonnull,
|
||||
_Nullable NSMergeReceiver *nullable,
|
||||
_Null_unspecified NSMergeReceiver *null_unspecified) {
|
||||
int *ptr;
|
||||
|
||||
ptr = [nullable returnsNullable]; // expected-warning{{'id __nullable'}}
|
||||
ptr = [nullable returnsNullUnspecified]; // expected-warning{{'id __nullable'}}
|
||||
ptr = [nullable returnsNonNull]; // expected-warning{{'id __nullable'}}
|
||||
ptr = [nullable returnsNone]; // expected-warning{{'id __nullable'}}
|
||||
ptr = [nullable returnsNullable]; // expected-warning{{'id _Nullable'}}
|
||||
ptr = [nullable returnsNullUnspecified]; // expected-warning{{'id _Nullable'}}
|
||||
ptr = [nullable returnsNonNull]; // expected-warning{{'id _Nullable'}}
|
||||
ptr = [nullable returnsNone]; // expected-warning{{'id _Nullable'}}
|
||||
|
||||
ptr = [null_unspecified returnsNullable]; // expected-warning{{'id __nullable'}}
|
||||
ptr = [null_unspecified returnsNullUnspecified]; // expected-warning{{'id __null_unspecified'}}
|
||||
ptr = [null_unspecified returnsNonNull]; // expected-warning{{'id __null_unspecified'}}
|
||||
ptr = [null_unspecified returnsNullable]; // expected-warning{{'id _Nullable'}}
|
||||
ptr = [null_unspecified returnsNullUnspecified]; // expected-warning{{'id _Null_unspecified'}}
|
||||
ptr = [null_unspecified returnsNonNull]; // expected-warning{{'id _Null_unspecified'}}
|
||||
ptr = [null_unspecified returnsNone]; // expected-warning{{'id'}}
|
||||
|
||||
ptr = [nonnull returnsNullable]; // expected-warning{{'id __nullable'}}
|
||||
ptr = [nonnull returnsNullUnspecified]; // expected-warning{{'id __null_unspecified'}}
|
||||
ptr = [nonnull returnsNonNull]; // expected-warning{{'id __nonnull'}}
|
||||
ptr = [nonnull returnsNullable]; // expected-warning{{'id _Nullable'}}
|
||||
ptr = [nonnull returnsNullUnspecified]; // expected-warning{{'id _Null_unspecified'}}
|
||||
ptr = [nonnull returnsNonNull]; // expected-warning{{'id _Nonnull'}}
|
||||
ptr = [nonnull returnsNone]; // expected-warning{{'id'}}
|
||||
|
||||
ptr = [none returnsNullable]; // expected-warning{{'id __nullable'}}
|
||||
ptr = [none returnsNullable]; // expected-warning{{'id _Nullable'}}
|
||||
ptr = [none returnsNullUnspecified]; // expected-warning{{'id'}}
|
||||
ptr = [none returnsNonNull]; // expected-warning{{'id'}}
|
||||
ptr = [none returnsNone]; // expected-warning{{'id'}}
|
||||
|
@ -157,19 +157,19 @@ __attribute__((objc_root_class))
|
|||
- (nullable instancetype)returnMe;
|
||||
+ (nullable instancetype)returnInstanceOfMe;
|
||||
|
||||
- (nonnull instancetype __nullable)initWithBlah2:(nonnull id)blah; // expected-error {{nullability specifier '__nullable' conflicts with existing specifier '__nonnull'}}
|
||||
- (instancetype __nullable)returnMe2;
|
||||
+ (__nonnull instancetype)returnInstanceOfMe2;
|
||||
- (nonnull instancetype _Nullable)initWithBlah2:(nonnull id)blah; // expected-error {{nullability specifier '_Nullable' conflicts with existing specifier '_Nonnull'}}
|
||||
- (instancetype _Nullable)returnMe2;
|
||||
+ (_Nonnull instancetype)returnInstanceOfMe2;
|
||||
@end
|
||||
|
||||
void test_instancetype(InitializableClass * __nonnull ic, id __nonnull object) {
|
||||
int *ip = [ic returnMe]; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'InitializableClass * __nullable'}}
|
||||
ip = [InitializableClass returnMe]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'id __nullable'}}
|
||||
ip = [InitializableClass returnInstanceOfMe]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'InitializableClass * __nullable'}}
|
||||
ip = [object returnMe]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'id __nullable'}}
|
||||
void test_instancetype(InitializableClass * _Nonnull ic, id _Nonnull object) {
|
||||
int *ip = [ic returnMe]; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'InitializableClass * _Nullable'}}
|
||||
ip = [InitializableClass returnMe]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'id _Nullable'}}
|
||||
ip = [InitializableClass returnInstanceOfMe]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'InitializableClass * _Nullable'}}
|
||||
ip = [object returnMe]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'id _Nullable'}}
|
||||
|
||||
ip = [ic returnMe2]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'InitializableClass * __nullable'}}
|
||||
ip = [InitializableClass returnInstanceOfMe2]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'InitializableClass * __nonnull'}}
|
||||
ip = [ic returnMe2]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'InitializableClass * _Nullable'}}
|
||||
ip = [InitializableClass returnInstanceOfMe2]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'InitializableClass * _Nonnull'}}
|
||||
}
|
||||
|
||||
// Check null_resettable getters/setters.
|
||||
|
@ -184,14 +184,14 @@ __attribute__((objc_root_class))
|
|||
@end
|
||||
|
||||
void test_null_resettable(NSResettable *r, int *ip) {
|
||||
[r setResettable1:ip]; // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'NSResettable * __nullable'}}
|
||||
r.resettable1 = ip; // expected-warning{{incompatible pointer types assigning to 'NSResettable * __nullable' from 'int *'}}
|
||||
[r setResettable1:ip]; // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'NSResettable * _Nullable'}}
|
||||
r.resettable1 = ip; // expected-warning{{incompatible pointer types assigning to 'NSResettable * _Nullable' from 'int *'}}
|
||||
}
|
||||
|
||||
@implementation NSResettable // expected-warning{{synthesized setter 'setResettable4:' for null_resettable property 'resettable4' does not handle nil}}
|
||||
- (NSResettable *)resettable1 {
|
||||
int *ip = 0;
|
||||
return ip; // expected-warning{{result type 'NSResettable * __nonnull'}}
|
||||
return ip; // expected-warning{{result type 'NSResettable * _Nonnull'}}
|
||||
}
|
||||
|
||||
- (void)setResettable1:(NSResettable *)param {
|
||||
|
@ -218,15 +218,15 @@ void test_null_resettable(NSResettable *r, int *ip) {
|
|||
|
||||
void testMultiProp(MultiProp *foo) {
|
||||
int *ip;
|
||||
ip = foo.a; // expected-warning{{from 'id __nullable'}}
|
||||
ip = foo.d; // expected-warning{{from 'MultiProp * __nullable'}}
|
||||
ip = foo.e; // expected-error{{incompatible type 'MultiProp *(^ __nullable)(int)'}}
|
||||
ip = foo.a; // expected-warning{{from 'id _Nullable'}}
|
||||
ip = foo.d; // expected-warning{{from 'MultiProp * _Nullable'}}
|
||||
ip = foo.e; // expected-error{{incompatible type 'MultiProp *(^ _Nullable)(int)'}}
|
||||
}
|
||||
|
||||
void testBlockLiterals() {
|
||||
(void)(^id(void) { return 0; });
|
||||
(void)(^id __nullable (void) { return 0; });
|
||||
(void)(^ __nullable id(void) { return 0; });
|
||||
(void)(^id _Nullable (void) { return 0; });
|
||||
(void)(^ _Nullable id(void) { return 0; });
|
||||
|
||||
int *x = (^ __nullable id(void) { return 0; })(); // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'id __nullable'}}
|
||||
int *x = (^ _Nullable id(void) { return 0; })(); // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'id _Nullable'}}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
@interface NSObject @end
|
||||
|
||||
@class NSFoo;
|
||||
void foo (NSFoo * __nonnull);
|
||||
void foo (NSFoo * _Nonnull);
|
||||
|
||||
@interface NSBar : NSObject
|
||||
@property(weak) NSFoo *property1;
|
||||
|
@ -13,6 +13,6 @@ void foo (NSFoo * __nonnull);
|
|||
|
||||
@implementation NSBar
|
||||
- (void) Meth {
|
||||
foo (self.property1); // expected-warning {{implicit conversion from nullable pointer 'NSFoo * __nullable' to non-nullable pointer type 'NSFoo * __nonnull'}}
|
||||
foo (self.property1); // expected-warning {{implicit conversion from nullable pointer 'NSFoo * _Nullable' to non-nullable pointer type 'NSFoo * _Nonnull'}}
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
void f1(int *ptr); // expected-warning{{pointer is missing a nullability type specifier}}
|
||||
|
||||
void f2(int * __nonnull);
|
||||
void f2(int * _Nonnull);
|
||||
|
||||
#include "nullability-consistency-2.h"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
void g1(int * __nonnull);
|
||||
void g1(int * _Nonnull);
|
||||
|
||||
void g2(int (^block)(int, int)); // expected-warning{{block pointer is missing a nullability type specifier}}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
void double_declarator1(int *__nonnull *); // expected-warning{{pointer is missing a nullability type specifier (__nonnull, __nullable, or __null_unspecified)}}
|
||||
void double_declarator1(int *_Nonnull *); // expected-warning{{pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
|
||||
|
|
|
@ -1 +1 @@
|
|||
void double_declarator1(int * * __nonnull); // expected-warning{{pointer is missing a nullability type specifier (__nonnull, __nullable, or __null_unspecified)}}
|
||||
void double_declarator1(int * * _Nonnull); // expected-warning{{pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)}}
|
||||
|
|
|
@ -8,7 +8,7 @@ void suppress1(SUPPRESS_NULLABILITY_WARNING(int *) ptr); // no warning
|
|||
|
||||
void shouldwarn5(int *ptr); //expected-warning{{missing a nullability type specifier}}
|
||||
|
||||
void trigger5(int * __nonnull);
|
||||
void trigger5(int * _Nonnull);
|
||||
|
||||
void suppress2(SUPPRESS_NULLABILITY_WARNING(int *) ptr); // no warning
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
typedef int* __nonnull mynonnull;
|
||||
typedef int* _Nonnull mynonnull;
|
||||
|
||||
__attribute__((objc_root_class))
|
||||
@interface typedefClass
|
||||
|
@ -13,15 +13,15 @@ void func3(int *); // expected-warning{{pointer is missing a nullability type sp
|
|||
typedef void *CFTypeRef;
|
||||
void cf1(CFTypeRef * p CF_RETURNS_NOT_RETAINED); // expected-warning {{pointer is missing a nullability type specifier}}
|
||||
|
||||
void cf2(CFTypeRef * __nullable p CF_RETURNS_NOT_RETAINED);
|
||||
void cf3(CFTypeRef * __nonnull p CF_RETURNS_NOT_RETAINED);
|
||||
void cf2(CFTypeRef * _Nullable p CF_RETURNS_NOT_RETAINED);
|
||||
void cf3(CFTypeRef * _Nonnull p CF_RETURNS_NOT_RETAINED);
|
||||
|
||||
void cf4(CFTypeRef __nullable * __nullable p CF_RETURNS_NOT_RETAINED);
|
||||
void cf5(CFTypeRef __nonnull * __nullable p CF_RETURNS_NOT_RETAINED);
|
||||
void cf4(CFTypeRef _Nullable * _Nullable p CF_RETURNS_NOT_RETAINED);
|
||||
void cf5(CFTypeRef _Nonnull * _Nullable p CF_RETURNS_NOT_RETAINED);
|
||||
|
||||
void cf6(CFTypeRef * __nullable CF_RETURNS_NOT_RETAINED p);
|
||||
void cf7(CF_RETURNS_NOT_RETAINED CFTypeRef * __nonnull p);
|
||||
void cf6(CFTypeRef * _Nullable CF_RETURNS_NOT_RETAINED p);
|
||||
void cf7(CF_RETURNS_NOT_RETAINED CFTypeRef * _Nonnull p);
|
||||
|
||||
typedef CFTypeRef __nullable *CFTypeRefPtr;
|
||||
typedef CFTypeRef _Nullable *CFTypeRefPtr;
|
||||
void cfp1(CFTypeRefPtr p CF_RETURNS_NOT_RETAINED); // expected-warning {{pointer is missing a nullability type specifier}}
|
||||
void cfp2(CFTypeRefPtr __nonnull p CF_RETURNS_NOT_RETAINED);
|
||||
void cfp2(CFTypeRefPtr _Nonnull p CF_RETURNS_NOT_RETAINED);
|
||||
|
|
|
@ -5,4 +5,4 @@ void system1(int *ptr);
|
|||
// expected-warning@-2{{pointer is missing a nullability type specifier}}
|
||||
#endif
|
||||
|
||||
void system2(int * __nonnull);
|
||||
void system2(int * _Nonnull);
|
||||
|
|
|
@ -25,19 +25,19 @@ void f3(A* obj);
|
|||
void f4(int (^block)(int, int));
|
||||
void f5(int_ptr x);
|
||||
void f6(A_ptr obj);
|
||||
void f7(int * __nullable x);
|
||||
void f8(A * __nullable obj);
|
||||
void f7(int * _Nullable x);
|
||||
void f8(A * _Nullable obj);
|
||||
void f9(int X::* mem_ptr);
|
||||
void f10(int (X::*mem_func)(int, int));
|
||||
void f11(int X::* __nullable mem_ptr);
|
||||
void f12(int (X::* __nullable mem_func)(int, int));
|
||||
void f11(int X::* _Nullable mem_ptr);
|
||||
void f12(int (X::* _Nullable mem_func)(int, int));
|
||||
|
||||
int_ptr f13(void);
|
||||
A *f14(void);
|
||||
|
||||
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}}
|
||||
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}}
|
||||
void f19(CFErrorRefPtr error); // expected-warning{{pointer is missing a nullability type specifier}}
|
||||
|
||||
|
@ -64,14 +64,14 @@ void g5(int (**fp)(int, int)); // expected-warning 2{{pointer is missing a nulla
|
|||
|
||||
int *global_int_ptr;
|
||||
|
||||
// typedefs not inferred __nonnull
|
||||
// typedefs not inferred _Nonnull
|
||||
typedef int *int_ptr_2;
|
||||
|
||||
typedef int * // expected-warning{{pointer is missing a nullability type specifier}}
|
||||
*int_ptr_ptr;
|
||||
|
||||
static inline void f30(void) {
|
||||
float *fp = global_int_ptr; // expected-error{{cannot initialize a variable of type 'float *' with an lvalue of type 'int * __nonnull'}}
|
||||
float *fp = global_int_ptr; // expected-error{{cannot initialize a variable of type 'float *' with an lvalue of type 'int * _Nonnull'}}
|
||||
|
||||
int_ptr_2 ip2;
|
||||
float *fp2 = ip2; // expected-error{{cannot initialize a variable of type 'float *' with an lvalue of type 'int_ptr_2' (aka 'int *')}}
|
||||
|
@ -83,7 +83,7 @@ static inline void f30(void) {
|
|||
@interface AA : A {
|
||||
@public
|
||||
id ivar1;
|
||||
__nonnull id ivar2;
|
||||
_Nonnull id ivar2;
|
||||
}
|
||||
@end
|
||||
|
||||
|
@ -92,8 +92,8 @@ static inline void f30(void) {
|
|||
void f20(A *a); // expected-warning{{pointer is missing a nullability type specifier}}
|
||||
void f21(int_ptr x); // expected-warning{{pointer is missing a nullability type specifier}}
|
||||
void f22(A_ptr y); // expected-warning{{pointer is missing a nullability type specifier}}
|
||||
void f23(int_ptr __nullable x);
|
||||
void f24(A_ptr __nullable y);
|
||||
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}}
|
||||
|
||||
@interface A(OutsidePragmas1)
|
||||
|
|
|
@ -13,4 +13,4 @@
|
|||
|
||||
void h1(int *ptr) { } // don't warn
|
||||
|
||||
void h2(int * __nonnull) { }
|
||||
void h2(int * _Nonnull) { }
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
# error assume_nonnull feature is not set
|
||||
#endif
|
||||
|
||||
void test_pragmas_1(A * __nonnull a, AA * __nonnull aa) {
|
||||
void test_pragmas_1(A * _Nonnull a, AA * _Nonnull aa) {
|
||||
f1(0); // okay: no nullability annotations
|
||||
f2(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
|
||||
f3(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
|
||||
|
@ -23,19 +23,19 @@ void test_pragmas_1(A * __nonnull a, AA * __nonnull aa) {
|
|||
[a method1:0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
|
||||
|
||||
f17(a); // expected-error{{no matching function for call to 'f17'}}
|
||||
[a method3: a]; // expected-error{{cannot initialize a parameter of type 'NSError * __nullable * __nullable' with an lvalue of type 'A * __nonnull'}}
|
||||
[a method4: a]; // expected-error{{cannot initialize a parameter of type 'NSErrorPtr __nullable * __nullable' (aka 'NSError **') with an lvalue of type 'A * __nonnull'}}
|
||||
[a method3: a]; // expected-error{{cannot initialize a parameter of type 'NSError * _Nullable * _Nullable' with an lvalue of type 'A * _Nonnull'}}
|
||||
[a method4: a]; // expected-error{{cannot initialize a parameter of type 'NSErrorPtr _Nullable * _Nullable' (aka 'NSError **') with an lvalue of type 'A * _Nonnull'}}
|
||||
|
||||
float *ptr;
|
||||
ptr = f13(); // expected-error{{assigning to 'float *' from incompatible type 'int_ptr __nonnull' (aka 'int *')}}
|
||||
ptr = f14(); // expected-error{{assigning to 'float *' from incompatible type 'A * __nonnull'}}
|
||||
ptr = [a method1:a]; // expected-error{{assigning to 'float *' from incompatible type 'A * __nonnull'}}
|
||||
ptr = a.aProp; // expected-error{{assigning to 'float *' from incompatible type 'A * __nonnull'}}
|
||||
ptr = global_int_ptr; // expected-error{{assigning to 'float *' from incompatible type 'int * __nonnull'}}
|
||||
ptr = f15(); // expected-error{{assigning to 'float *' from incompatible type 'int * __null_unspecified'}}
|
||||
ptr = f16(); // expected-error{{assigning to 'float *' from incompatible type 'A * __null_unspecified'}}
|
||||
ptr = [a method2]; // expected-error{{assigning to 'float *' from incompatible type 'A * __null_unspecified'}}
|
||||
ptr = f13(); // expected-error{{assigning to 'float *' from incompatible type 'int_ptr _Nonnull' (aka 'int *')}}
|
||||
ptr = f14(); // expected-error{{assigning to 'float *' from incompatible type 'A * _Nonnull'}}
|
||||
ptr = [a method1:a]; // expected-error{{assigning to 'float *' from incompatible type 'A * _Nonnull'}}
|
||||
ptr = a.aProp; // expected-error{{assigning to 'float *' from incompatible type 'A * _Nonnull'}}
|
||||
ptr = global_int_ptr; // expected-error{{assigning to 'float *' from incompatible type 'int * _Nonnull'}}
|
||||
ptr = f15(); // expected-error{{assigning to 'float *' from incompatible type 'int * _Null_unspecified'}}
|
||||
ptr = f16(); // expected-error{{assigning to 'float *' from incompatible type 'A * _Null_unspecified'}}
|
||||
ptr = [a method2]; // expected-error{{assigning to 'float *' from incompatible type 'A * _Null_unspecified'}}
|
||||
|
||||
ptr = aa->ivar1; // expected-error{{from incompatible type 'id'}}
|
||||
ptr = aa->ivar2; // expected-error{{from incompatible type 'id __nonnull'}}
|
||||
ptr = aa->ivar2; // expected-error{{from incompatible type 'id _Nonnull'}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue