summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2014-02-08 00:04:14 +0000
committerJordan Rose <jordan_rose@apple.com>2014-02-08 00:04:14 +0000
commit4393aa7efb0829f463911f783d87e8a9f039ffbd (patch)
tree6f381ea92e2495d3c60cde1daef1f23833e96a7a /clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
parentb3b52a753207f1d910fce17f9b354141e8e28fd7 (diff)
downloadbcm5719-llvm-4393aa7efb0829f463911f783d87e8a9f039ffbd.tar.gz
bcm5719-llvm-4393aa7efb0829f463911f783d87e8a9f039ffbd.zip
[analyzer] Objective-C object literals are always non-nil.
<rdar://problem/15999214> llvm-svn: 201007
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp30
1 files changed, 26 insertions, 4 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
index 3384d4bc066..adf1b239421 100644
--- a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -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);
OpenPOWER on IntegriCloud