diff options
Diffstat (limited to 'test/Analysis/nullability_nullonly.mm')
-rw-r--r-- | test/Analysis/nullability_nullonly.mm | 91 |
1 files changed, 87 insertions, 4 deletions
diff --git a/test/Analysis/nullability_nullonly.mm b/test/Analysis/nullability_nullonly.mm index 56b3f9e14490..9671877719f3 100644 --- a/test/Analysis/nullability_nullonly.mm +++ b/test/Analysis/nullability_nullonly.mm @@ -1,4 +1,7 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -verify %s +// RUN: %clang_cc1 -analyze -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -DNOSYSTEMHEADERS=0 -verify %s +// RUN: %clang_cc1 -analyze -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -DNOSYSTEMHEADERS=1 -verify %s + +#include "Inputs/system-header-simulator-for-nullability.h" int getRandom(); @@ -15,18 +18,18 @@ void testBasicRules() { Dummy *q = 0; if (getRandom()) { takesNullable(q); - takesNonnull(q); // expected-warning {{}} + takesNonnull(q); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}} } } Dummy *_Nonnull testNullReturn() { Dummy *p = 0; - return p; // expected-warning {{}} + return p; // expected-warning {{Null is returned from a function that is expected to return a non-null value}} } void onlyReportFirstPreconditionViolationOnPath() { Dummy *p = 0; - takesNonnull(p); // expected-warning {{}} + takesNonnull(p); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}} takesNonnull(p); // No warning. // Passing null to nonnull is a sink. Stop the analysis. int i = 0; @@ -85,3 +88,83 @@ Dummy *_Nonnull testDefensiveInlineChecks(Dummy * p) { takesNonnull(p); return p; } + +@interface TestObject : NSObject +@end + +TestObject *_Nonnull getNonnullTestObject(); + +void testObjCARCImplicitZeroInitialization() { + TestObject * _Nonnull implicitlyZeroInitialized; // no-warning + implicitlyZeroInitialized = getNonnullTestObject(); +} + +void testObjCARCExplicitZeroInitialization() { + TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{Null is assigned to a pointer which is expected to have non-null value}} +} + +// Under ARC, returned expressions of ObjC objects types are are implicitly +// cast to _Nonnull when the functions return type is _Nonnull, so make +// sure this doesn't implicit cast doesn't suppress a legitimate warning. +TestObject * _Nonnull returnsNilObjCInstanceIndirectly() { + TestObject *local = 0; + return local; // expected-warning {{Null is returned from a function that is expected to return a non-null value}} +} + +TestObject * _Nonnull returnsNilObjCInstanceIndirectlyWithSupressingCast() { + TestObject *local = 0; + return (TestObject * _Nonnull)local; // no-warning +} + +TestObject * _Nonnull returnsNilObjCInstanceDirectly() { + return nil; // expected-warning {{Null is returned from a function that is expected to return a non-null value}} +} + +TestObject * _Nonnull returnsNilObjCInstanceDirectlyWithSuppressingCast() { + return (TestObject * _Nonnull)nil; // no-warning +} + +@interface SomeClass : NSObject +@end + +@implementation SomeClass (MethodReturn) +- (SomeClass * _Nonnull)testReturnsNilInNonnull { + SomeClass *local = nil; + return local; // expected-warning {{Null is returned from a method that is expected to return a non-null value}} +} + +- (SomeClass * _Nonnull)testReturnsCastSuppressedNilInNonnull { + SomeClass *local = nil; + return (SomeClass * _Nonnull)local; // no-warning +} + +- (SomeClass * _Nonnull)testReturnsNilInNonnullWhenPreconditionViolated:(SomeClass * _Nonnull) p { + SomeClass *local = nil; + if (!p) // Pre-condition violated here. + return local; // no-warning + else + return p; // no-warning +} +@end + + +void callFunctionInSystemHeader() { + NSString *s; + s = nil; + + NSSystemFunctionTakingNonnull(s); + #if !NOSYSTEMHEADERS + // expected-warning@-2{{Null passed to a callee that requires a non-null 1st parameter}} + #endif +} + +void callMethodInSystemHeader() { + NSString *s; + s = nil; + + NSSystemClass *sc = [[NSSystemClass alloc] init]; + [sc takesNonnull:s]; + #if !NOSYSTEMHEADERS + // expected-warning@-2{{Null passed to a callee that requires a non-null 1st parameter}} + #endif +} |