diff options
author | Jordan Rose <jordan_rose@apple.com> | 2014-02-08 00:04:14 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2014-02-08 00:04:14 +0000 |
commit | 4393aa7efb0829f463911f783d87e8a9f039ffbd (patch) | |
tree | 6f381ea92e2495d3c60cde1daef1f23833e96a7a /clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp | |
parent | b3b52a753207f1d910fce17f9b354141e8e28fd7 (diff) | |
download | bcm5719-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.cpp | 30 |
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); |