r201007 - [analyzer] Objective-C object literals are always non-nil.

Jordan Rose jordan_rose at apple.com
Fri Feb 7 16:04:15 PST 2014


Author: jrose
Date: Fri Feb  7 18:04:14 2014
New Revision: 201007

URL: http://llvm.org/viewvc/llvm-project?rev=201007&view=rev
Log:
[analyzer] Objective-C object literals are always non-nil.

<rdar://problem/15999214>

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
    cfe/trunk/test/Analysis/NSContainers.m
    cfe/trunk/test/Analysis/objc-boxing.m

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp?rev=201007&r1=201006&r2=201007&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp Fri Feb  7 18:04:14 2014
@@ -1139,7 +1139,10 @@ namespace {
 /// \brief The checker restricts the return values of APIs known to
 /// never (or almost never) return 'nil'.
 class ObjCNonNilReturnValueChecker
-  : public Checker<check::PostObjCMessage> {
+  : public Checker<check::PostObjCMessage,
+                   check::PostStmt<ObjCArrayLiteral>,
+                   check::PostStmt<ObjCDictionaryLiteral>,
+                   check::PostStmt<ObjCBoxedExpr> > {
     mutable bool Initialized;
     mutable Selector ObjectAtIndex;
     mutable Selector ObjectAtIndexedSubscript;
@@ -1147,13 +1150,32 @@ class ObjCNonNilReturnValueChecker
 
 public:
   ObjCNonNilReturnValueChecker() : Initialized(false) {}
+
+  ProgramStateRef assumeExprIsNonNull(const Expr *NonNullExpr,
+                                      ProgramStateRef State,
+                                      CheckerContext &C) const;
+  void assumeExprIsNonNull(const Expr *E, CheckerContext &C) const {
+    C.addTransition(assumeExprIsNonNull(E, C.getState(), C));
+  }
+
+  void checkPostStmt(const ObjCArrayLiteral *E, CheckerContext &C) const {
+    assumeExprIsNonNull(E, C);
+  }
+  void checkPostStmt(const ObjCDictionaryLiteral *E, CheckerContext &C) const {
+    assumeExprIsNonNull(E, C);
+  }
+  void checkPostStmt(const ObjCBoxedExpr *E, CheckerContext &C) const {
+    assumeExprIsNonNull(E, C);
+  }
+
   void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const;
 };
 }
 
-static ProgramStateRef assumeExprIsNonNull(const Expr *NonNullExpr,
-                                           ProgramStateRef State,
-                                           CheckerContext &C) {
+ProgramStateRef
+ObjCNonNilReturnValueChecker::assumeExprIsNonNull(const Expr *NonNullExpr,
+                                                  ProgramStateRef State,
+                                                  CheckerContext &C) const {
   SVal Val = State->getSVal(NonNullExpr, C.getLocationContext());
   if (Optional<DefinedOrUnknownSVal> DV = Val.getAs<DefinedOrUnknownSVal>())
     return State->assume(*DV, true);

Modified: cfe/trunk/test/Analysis/NSContainers.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/NSContainers.m?rev=201007&r1=201006&r2=201007&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/NSContainers.m (original)
+++ cfe/trunk/test/Analysis/NSContainers.m Fri Feb  7 18:04:14 2014
@@ -1,4 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.NonNilReturnValue,osx.cocoa.NilArg,osx.cocoa.Loops -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.NonNilReturnValue,osx.cocoa.NilArg,osx.cocoa.Loops,debug.ExprInspection -verify -Wno-objc-root-class %s
+
+void clang_analyzer_eval(int);
+
 typedef unsigned long NSUInteger;
 typedef signed char BOOL;
 typedef struct _NSZone NSZone;
@@ -276,3 +279,8 @@ void testCountAwareNSOrderedSet(NSOrdere
 	}
 }
 
+void testLiteralsNonNil() {
+  clang_analyzer_eval(!!@[]); // expected-warning{{TRUE}}
+  clang_analyzer_eval(!!@{}); // expected-warning{{TRUE}}
+}
+

Modified: cfe/trunk/test/Analysis/objc-boxing.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/objc-boxing.m?rev=201007&r1=201006&r2=201007&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/objc-boxing.m (original)
+++ cfe/trunk/test/Analysis/objc-boxing.m Fri Feb  7 18:04:14 2014
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,osx.cocoa.NonNilReturnValue,debug.ExprInspection -analyzer-store=region -verify %s
+
+void clang_analyzer_eval(int);
 
 typedef signed char BOOL;
 typedef long NSInteger;
@@ -41,4 +43,15 @@ id const_char_pointer(int *x) {
   if (x)
     return @(3);
   return @(*x); // expected-warning {{Dereference of null pointer (loaded from variable 'x')}}
-}
\ No newline at end of file
+}
+
+void checkNonNil() {
+  clang_analyzer_eval(!!@3); // expected-warning{{TRUE}}
+  clang_analyzer_eval(!!@(3+4)); // expected-warning{{TRUE}}
+  clang_analyzer_eval(!!@(57.0)); // expected-warning{{TRUE}}
+
+  const char *str = "abc";
+  clang_analyzer_eval(!!@(str)); // expected-warning{{TRUE}}
+  clang_analyzer_eval(!!@__objc_yes); // expected-warning{{TRUE}}
+}
+





More information about the cfe-commits mailing list