Files
clang-p2996/clang/test/Analysis/nullability_nullonly.mm
Devin Coughlin a1d9d75a88 [analyzer] Nullability: add option to not report on calls to system headers.
Add an -analyzer-config 'nullability:NoDiagnoseCallsToSystemHeaders' option to
the nullability checker. When enabled, this option causes the analyzer to not
report about passing null/nullable values to functions and methods declared
in system headers.

This option is motivated by the observation that large projects may have many
nullability warnings. These projects may find warnings about nullability
annotations that they have explicitly added themselves higher priority to fix
than warnings on calls to system libraries.

llvm-svn: 262763
2016-03-05 01:32:43 +00:00

171 lines
5.0 KiB
Plaintext

// 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();
typedef struct Dummy { int val; } Dummy;
void takesNullable(Dummy *_Nullable);
void takesNonnull(Dummy *_Nonnull);
Dummy *_Nullable returnsNullable();
void testBasicRules() {
// The tracking of nullable values is turned off.
Dummy *p = returnsNullable();
takesNonnull(p); // no warning
Dummy *q = 0;
if (getRandom()) {
takesNullable(q);
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 {{Null is returned from a function that is expected to return a non-null value}}
}
void onlyReportFirstPreconditionViolationOnPath() {
Dummy *p = 0;
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;
i = 5 / i; // no warning
(void)i;
}
Dummy *_Nonnull doNotWarnWhenPreconditionIsViolatedInTopFunc(
Dummy *_Nonnull p) {
if (!p) {
Dummy *ret =
0; // avoid compiler warning (which is not generated by the analyzer)
if (getRandom())
return ret; // no warning
else
return p; // no warning
} else {
return p;
}
}
Dummy *_Nonnull doNotWarnWhenPreconditionIsViolated(Dummy *_Nonnull p) {
if (!p) {
Dummy *ret =
0; // avoid compiler warning (which is not generated by the analyzer)
if (getRandom())
return ret; // no warning
else
return p; // no warning
} else {
return p;
}
}
void testPreconditionViolationInInlinedFunction(Dummy *p) {
doNotWarnWhenPreconditionIsViolated(p);
}
void inlinedNullable(Dummy *_Nullable p) {
if (p) return;
}
void inlinedNonnull(Dummy *_Nonnull p) {
if (p) return;
}
void inlinedUnspecified(Dummy *p) {
if (p) return;
}
Dummy *_Nonnull testDefensiveInlineChecks(Dummy * p) {
switch (getRandom()) {
case 1: inlinedNullable(p); break;
case 2: inlinedNonnull(p); break;
case 3: inlinedUnspecified(p); break;
}
if (getRandom())
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
}