diff options
author | Anna Zaks <ganna@apple.com> | 2013-05-10 18:04:46 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2013-05-10 18:04:46 +0000 |
commit | 4063fa1cdc0782c5d90c2c0a5bc05036d9587915 (patch) | |
tree | bd5b2c28160914e63ad6fbc4c859be1a118f3891 /clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp | |
parent | 3feb2cd5bbbeeba4a7dba3179ec6f93fc3cbb6c8 (diff) | |
download | bcm5719-llvm-4063fa1cdc0782c5d90c2c0a5bc05036d9587915.tar.gz bcm5719-llvm-4063fa1cdc0782c5d90c2c0a5bc05036d9587915.zip |
[analyzer] Assume [NSNull null] does not return nil.
llvm-svn: 181616
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp index fba14a0fc49..6388a8df648 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp @@ -58,6 +58,7 @@ enum FoundationClass { FC_NSArray, FC_NSDictionary, FC_NSEnumerator, + FC_NSNull, FC_NSOrderedSet, FC_NSSet, FC_NSString @@ -69,6 +70,7 @@ static FoundationClass findKnownClass(const ObjCInterfaceDecl *ID) { Classes["NSArray"] = FC_NSArray; Classes["NSDictionary"] = FC_NSDictionary; Classes["NSEnumerator"] = FC_NSEnumerator; + Classes["NSNull"] = FC_NSNull; Classes["NSOrderedSet"] = FC_NSOrderedSet; Classes["NSSet"] = FC_NSSet; Classes["NSString"] = FC_NSString; @@ -845,6 +847,7 @@ class ObjCNonNilReturnValueChecker mutable bool Initialized; mutable Selector ObjectAtIndex; mutable Selector ObjectAtIndexedSubscript; + mutable Selector NullSelector; public: ObjCNonNilReturnValueChecker() : Initialized(false) {} @@ -870,6 +873,7 @@ void ObjCNonNilReturnValueChecker::checkPostObjCMessage(const ObjCMethodCall &M, ASTContext &Ctx = C.getASTContext(); ObjectAtIndex = GetUnarySelector("objectAtIndex", Ctx); ObjectAtIndexedSubscript = GetUnarySelector("objectAtIndexedSubscript", Ctx); + NullSelector = GetNullarySelector("null", Ctx); } // Check the receiver type. @@ -889,10 +893,11 @@ void ObjCNonNilReturnValueChecker::checkPostObjCMessage(const ObjCMethodCall &M, State = assumeExprIsNonNull(M.getOriginExpr(), State, C); } + FoundationClass Cl = findKnownClass(Interface); + // Objects returned from // [NSArray|NSOrderedSet]::[ObjectAtIndex|ObjectAtIndexedSubscript] // are never 'nil'. - FoundationClass Cl = findKnownClass(Interface); if (Cl == FC_NSArray || Cl == FC_NSOrderedSet) { Selector Sel = M.getSelector(); if (Sel == ObjectAtIndex || Sel == ObjectAtIndexedSubscript) { @@ -900,6 +905,14 @@ void ObjCNonNilReturnValueChecker::checkPostObjCMessage(const ObjCMethodCall &M, State = assumeExprIsNonNull(M.getOriginExpr(), State, C); } } + + // Objects returned from [NSNull null] are not nil. + if (Cl == FC_NSNull) { + if (M.getSelector() == NullSelector) { + // Go ahead and assume the value is non-nil. + State = assumeExprIsNonNull(M.getOriginExpr(), State, C); + } + } } C.addTransition(State); } |