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