diff options
author | Devin Coughlin <dcoughlin@apple.com> | 2016-04-13 00:41:54 +0000 |
---|---|---|
committer | Devin Coughlin <dcoughlin@apple.com> | 2016-04-13 00:41:54 +0000 |
commit | b2d2a018d6383f6e568de4de056f80433f32bf5f (patch) | |
tree | a1a7fbf1c903e46adf44dcf01b42cd922300274c /clang/test | |
parent | 887d4767b74bf9be18d81b1f4884a220697a921f (diff) | |
download | bcm5719-llvm-b2d2a018d6383f6e568de4de056f80433f32bf5f.tar.gz bcm5719-llvm-b2d2a018d6383f6e568de4de056f80433f32bf5f.zip |
[analyzer] Nullability: Treat nil _Nonnull ivar as invariant violation.
Treat a _Nonnull ivar that is nil as an invariant violation in a similar
fashion to how a nil _Nonnull parameter is treated as a precondition violation.
This avoids warning on defensive returns of nil on defensive internal
checks, such as the following common idiom:
@class InternalImplementation
@interface PublicClass {
InternalImplementation * _Nonnull _internal;
}
-(id _Nonnull)foo;
@end
@implementation PublicClass
-(id _Nonnull)foo {
if (!_internal)
return nil; // no-warning
return [_internal foo];
}
@end
rdar://problem/24485171
llvm-svn: 266157
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/Analysis/nullability.mm | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/clang/test/Analysis/nullability.mm b/clang/test/Analysis/nullability.mm index 1e01cdf4ca6..d4deecd9b5b 100644 --- a/clang/test/Analysis/nullability.mm +++ b/clang/test/Analysis/nullability.mm @@ -444,3 +444,45 @@ void callMethodInSystemHeader() { // expected-warning@-2{{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} #endif } + +// Test to make sure the analyzer doesn't warn when an a nullability invariant +// has already been found to be violated on an instance variable. + +@class MyInternalClass; +@interface MyClass : NSObject { + MyInternalClass * _Nonnull _internal; +} +@end + +@interface MyInternalClass : NSObject { + @public + id _someIvar; +} +-(id _Nonnull)methodWithInternalImplementation; +@end + +@interface MyClass () { + MyInternalClass * _Nonnull _nilledOutInternal; +} +@end + +@implementation MyClass +-(id _Nonnull)methodWithInternalImplementation { + if (!_internal) + return nil; // no-warning + + return [_internal methodWithInternalImplementation]; +} + +- (id _Nonnull)methodReturningIvarInImplementation; { + return _internal == 0 ? nil : _internal->_someIvar; // no-warning +} + +-(id _Nonnull)methodWithNilledOutInternal { + // The cast below should (but does not yet) suppress the warning on the + // assignment. + _nilledOutInternal = (id _Nonnull)nil; // expected-warning {{Null is assigned to a pointer which is expected to have non-null value}} + + return nil; // no-warning +} +@end |