diff options
author | Devin Coughlin <dcoughlin@apple.com> | 2015-06-15 01:00:42 +0000 |
---|---|---|
committer | Devin Coughlin <dcoughlin@apple.com> | 2015-06-15 01:00:42 +0000 |
commit | 0bee1d7ff1e14fffbc6bbdf50e5324ea4c92aeef (patch) | |
tree | dbf388172bc7110d5cb8d95cb1f3d5dcb0f7cdcf /clang/lib/StaticAnalyzer | |
parent | b11df184ad642c8601d4073fff54974fd76b70c7 (diff) | |
download | bcm5719-llvm-0bee1d7ff1e14fffbc6bbdf50e5324ea4c92aeef.tar.gz bcm5719-llvm-0bee1d7ff1e14fffbc6bbdf50e5324ea4c92aeef.zip |
[analyzer] Remove ObjCContainersChecker size information when a CFMutableArrayRef escapes
Update ObjCContainersChecker to be notified when pointers escape so it can
remove size information for escaping CFMutableArrayRefs. When such pointers
escape, un-analyzed code could mutate the array and cause the size information
to be incorrect.
rdar://problem/19406485
llvm-svn: 239709
Diffstat (limited to 'clang/lib/StaticAnalyzer')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp index d1938a0f7f7..4f0b7e51da1 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp @@ -29,7 +29,8 @@ using namespace ento; namespace { class ObjCContainersChecker : public Checker< check::PreStmt<CallExpr>, - check::PostStmt<CallExpr> > { + check::PostStmt<CallExpr>, + check::PointerEscape> { mutable std::unique_ptr<BugType> BT; inline void initBugType() const { if (!BT) @@ -52,6 +53,10 @@ public: void checkPostStmt(const CallExpr *CE, CheckerContext &C) const; void checkPreStmt(const CallExpr *CE, CheckerContext &C) const; + ProgramStateRef checkPointerEscape(ProgramStateRef State, + const InvalidatedSymbols &Escaped, + const CallEvent *Call, + PointerEscapeKind Kind) const; }; } // end anonymous namespace @@ -146,6 +151,24 @@ void ObjCContainersChecker::checkPreStmt(const CallExpr *CE, } } +ProgramStateRef +ObjCContainersChecker::checkPointerEscape(ProgramStateRef State, + const InvalidatedSymbols &Escaped, + const CallEvent *Call, + PointerEscapeKind Kind) const { + for (InvalidatedSymbols::const_iterator I = Escaped.begin(), + E = Escaped.end(); + I != E; ++I) { + SymbolRef Sym = *I; + // When a symbol for a mutable array escapes, we can't reason precisely + // about its size any more -- so remove it from the map. + // Note that we aren't notified here when a CFMutableArrayRef escapes as a + // CFArrayRef. This is because CFArrayRef is typedef'd as a pointer to a + // const-qualified type. + State = State->remove<ArraySizeMap>(Sym); + } + return State; +} /// Register checker. void ento::registerObjCContainersChecker(CheckerManager &mgr) { mgr.registerChecker<ObjCContainersChecker>(); |