r181616 - [analyzer] Assume [NSNull null] does not return nil.
Anna Zaks
ganna at apple.com
Fri May 10 11:04:46 PDT 2013
Author: zaks
Date: Fri May 10 13:04:46 2013
New Revision: 181616
URL: http://llvm.org/viewvc/llvm-project?rev=181616&view=rev
Log:
[analyzer] Assume [NSNull null] does not return nil.
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
cfe/trunk/test/Analysis/NSContainers.m
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp?rev=181616&r1=181615&r2=181616&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp Fri May 10 13:04:46 2013
@@ -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(co
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::check
ASTContext &Ctx = C.getASTContext();
ObjectAtIndex = GetUnarySelector("objectAtIndex", Ctx);
ObjectAtIndexedSubscript = GetUnarySelector("objectAtIndexedSubscript", Ctx);
+ NullSelector = GetNullarySelector("null", Ctx);
}
// Check the receiver type.
@@ -889,16 +893,25 @@ void ObjCNonNilReturnValueChecker::check
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) {
// Go ahead and assume the value is non-nil.
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);
Modified: cfe/trunk/test/Analysis/NSContainers.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/NSContainers.m?rev=181616&r1=181615&r2=181616&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/NSContainers.m (original)
+++ cfe/trunk/test/Analysis/NSContainers.m Fri May 10 13:04:46 2013
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.NilArg -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.NonNilReturnValue,osx.cocoa.NilArg -verify -Wno-objc-root-class %s
typedef unsigned long NSUInteger;
typedef signed char BOOL;
typedef struct _NSZone NSZone;
@@ -81,6 +81,10 @@ typedef struct _NSZone NSZone;
@end
+ at interface NSNull : NSObject <NSCopying, NSSecureCoding>
++ (NSNull *)null;
+ at end
+
// NSMutableArray API
void testNilArgNSMutableArray1() {
NSMutableArray *marray = [[NSMutableArray alloc] init];
@@ -197,4 +201,13 @@ void testNilReceiverRetNil2(NSMutableDic
[D setObject: value forKey: key]; // no-warning
}
+void testAssumeNSNullNullReturnsNonNil(NSMutableDictionary *Table, id Object,
+ id InValue) {
+ id Value = Object ? [Table objectForKey:Object] : [NSNull null];
+ if (!Value) {
+ Value = InValue;
+ [Table setObject:Value forKey:Object]; // no warning
+ }
+}
+
More information about the cfe-commits
mailing list