CLANG WARN NULLABLE TO NONNULL CONVERSION
Xcode 7 includes a project setting named "Apple LLVM 7.0 - Warnings - All languages > Incorrect Uses of Nullable Values", or CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION
.
You can pass it as a compiler flag using -Wnullable-to-nonnull-conversion
.
What does it do?
To demonstrate, consider the following command-line app:
Notice that we're passing a nil
literal to our function welcomeToClowntown()
, even though it takes a parameter of type NSString *_Nonnull
. This always emits a warning, regardless of whether CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION
is enabled.
But what about the following case?
welcomeToClowntown()
insists upon being given an NSString *_Nonnull
parameter, but we're passing it the return value from clownyGreeting()
, which is of type NSString *_Nullable
. In other words, we're passing a potentially nil
value to a function that requires non-nil
values. CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION
emits a warning for code such as this.
When should I use it?
I recommend enabling this setting before adding nullability identifiers to your Objective-C headers. That way, as you add restrictions on the non-nullability of your interfaces, the compiler will warn you of callsites that violate these restrictions.
Is it fool-proof?
No. Like many compiler warnings, it can be side-stepped:
When we assign the return value of clownyGreeting()
, an NSString *_Nonnull
object, to a variable typed as NSString *
, the compiler no longer emits a warning. I believe this is because the NSString *_Nonnull
object being returned is "cast" as an NSString *
, which is implicitly regarded as _Nonnull
.
Why shouldn't I enable this warning?
Nullability identifiers have been added to Foundation classes like NSString
, and some of these are very strict. For example, -[NSString isEqualToString:]
takes an argument of NSString *_Nonnull
. If you have a lot of callsites to this method that expect -isEqualToString:
to return NO
when passed a nil
parameter (JSON parsing, perhaps?), you'll have to modify each of those callsites.
This gets pretty tedious, so beware: turning CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION
on in your project could lead to a lot of extra warnings!
Still, all the warnings demonstrate spots where nil
may be propagating throughout your system. Try turning it on to see if the results surprise you!
Thanks to @nlutsenko for introducing me to this setting!
UPDATE: Clang static analyzer improvements
The latest version of the Clang static analyzer was released on October 28, 2015. It catches the "side-step" I point out above:
This is great work, and I can't wait for this new analyzer to be packaged with Xcode. Until then, you can run the analyzer yourself by downloading the latest release and running:
$ checker-277/scan-build \
-enable-checker nullability.NullPassedToNonnull \
-enable-checker nullability.NullReturnedFromNonnull \
-enable-checker nullability.NullableDereferenced \
-enable-checker nullability.NullablePassedToNonnull \
xcodebuild