[cfe-commits] r130711 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/ include/clang/StaticAnalyzer/Core/PathSensitive/ lib/StaticAnalyzer/Checkers/ lib/StaticAnalyzer/Core/ test/Analysis/
Ted Kremenek
kremenek at apple.com
Mon May 2 12:42:43 PDT 2011
Author: kremenek
Date: Mon May 2 14:42:42 2011
New Revision: 130711
URL: http://llvm.org/viewvc/llvm-project?rev=130711&view=rev
Log:
Augment retain/release checker to not warn about tracked objects passed as arguments to C++ constructors. This is a stop-gap measure for Objective-C++ code that uses smart pointers to manage reference counts.
Added:
cfe/trunk/test/Analysis/retain-release.mm
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h
cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/BasicStore.cpp
cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp
cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Core/FlatStore.cpp
cfe/trunk/lib/StaticAnalyzer/Core/GRState.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
cfe/trunk/test/Analysis/retain-release.m
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h Mon May 2 14:42:42 2011
@@ -240,9 +240,11 @@
class RegionChanges {
template <typename CHECKER>
static const GRState *_checkRegionChanges(void *checker, const GRState *state,
+ const StoreManager::InvalidatedSymbols *invalidated,
const MemRegion * const *Begin,
const MemRegion * const *End) {
- return ((const CHECKER *)checker)->checkRegionChanges(state, Begin, End);
+ return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
+ Begin, End);
}
template <typename CHECKER>
static bool _wantsRegionChangeUpdate(void *checker, const GRState *state) {
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h Mon May 2 14:42:42 2011
@@ -18,6 +18,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
#include <vector>
namespace clang {
@@ -49,6 +50,18 @@
template <typename T> class CheckerFn;
+template <typename RET, typename P1, typename P2, typename P3, typename P4>
+class CheckerFn<RET(P1, P2, P3, P4)> {
+ typedef RET (*Func)(void *, P1, P2, P3, P4);
+ Func Fn;
+public:
+ void *Checker;
+ CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
+ RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const {
+ return Fn(Checker, p1, p2, p3, p4);
+ }
+};
+
template <typename RET, typename P1, typename P2, typename P3>
class CheckerFn<RET(P1, P2, P3)> {
typedef RET (*Func)(void *, P1, P2, P3);
@@ -224,9 +237,11 @@
bool wantsRegionChangeUpdate(const GRState *state);
/// \brief Run checkers for region changes.
- const GRState *runCheckersForRegionChanges(const GRState *state,
- const MemRegion * const *Begin,
- const MemRegion * const *End);
+ const GRState *
+ runCheckersForRegionChanges(const GRState *state,
+ const StoreManager::InvalidatedSymbols *invalidated,
+ const MemRegion * const *Begin,
+ const MemRegion * const *End);
/// \brief Run checkers for handling assumptions on symbolic values.
const GRState *runCheckersForEvalAssume(const GRState *state,
@@ -283,6 +298,7 @@
typedef CheckerFn<void (const GRState *,SymbolReaper &)> CheckLiveSymbolsFunc;
typedef CheckerFn<const GRState * (const GRState *,
+ const StoreManager::InvalidatedSymbols *symbols,
const MemRegion * const *begin,
const MemRegion * const *end)>
CheckRegionChangesFunc;
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Mon May 2 14:42:42 2011
@@ -188,9 +188,11 @@
/// processRegionChanges - Called by GRStateManager whenever a change is made
/// to the store. Used to update checkers that track region values.
- const GRState* processRegionChanges(const GRState *state,
- const MemRegion * const *Begin,
- const MemRegion * const *End);
+ const GRState *
+ processRegionChanges(const GRState *state,
+ const StoreManager::InvalidatedSymbols *invalidated,
+ const MemRegion * const *Begin,
+ const MemRegion * const *End);
virtual GRStateManager& getStateManager() { return StateMgr; }
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h Mon May 2 14:42:42 2011
@@ -368,6 +368,12 @@
assert(refCount > 0);
--refCount;
}
+
+ const GRState *invalidateRegionsImpl(const MemRegion * const *Begin,
+ const MemRegion * const *End,
+ const Expr *E, unsigned BlockCount,
+ StoreManager::InvalidatedSymbols &IS,
+ bool invalidateGlobals) const;
};
class GRStateSet {
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h Mon May 2 14:42:42 2011
@@ -188,7 +188,7 @@
const MemRegion * const *Begin,
const MemRegion * const *End,
const Expr *E, unsigned Count,
- InvalidatedSymbols *IS,
+ InvalidatedSymbols &IS,
bool invalidateGlobals,
InvalidatedRegions *Regions) = 0;
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h Mon May 2 14:42:42 2011
@@ -15,6 +15,7 @@
#include "clang/Analysis/ProgramPoint.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
namespace clang {
@@ -95,13 +96,17 @@
/// processRegionChanges - Called by GRStateManager whenever a change is made
/// to the store. Used to update checkers that track region values.
- virtual const GRState* processRegionChanges(const GRState* state,
- const MemRegion* const *Begin,
- const MemRegion* const *End) = 0;
-
- inline const GRState* processRegionChange(const GRState* state,
- const MemRegion* MR) {
- return processRegionChanges(state, &MR, &MR+1);
+ virtual const GRState *
+ processRegionChanges(const GRState *state,
+ const StoreManager::InvalidatedSymbols *invalidated,
+ const MemRegion* const *Begin,
+ const MemRegion* const *End) = 0;
+
+
+ inline const GRState *
+ processRegionChange(const GRState* state,
+ const MemRegion* MR) {
+ return processRegionChanges(state, 0, &MR, &MR+1);
}
/// Called by CoreEngine when the analysis worklist is either empty or the
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp Mon May 2 14:42:42 2011
@@ -42,6 +42,7 @@
bool wantsRegionChangeUpdate(const GRState *state) const;
const GRState *checkRegionChanges(const GRState *state,
+ const StoreManager::InvalidatedSymbols *,
const MemRegion * const *Begin,
const MemRegion * const *End) const;
@@ -1305,6 +1306,7 @@
const GRState *
CStringChecker::checkRegionChanges(const GRState *state,
+ const StoreManager::InvalidatedSymbols *,
const MemRegion * const *Begin,
const MemRegion * const *End) const {
CStringLength::EntryMap Entries = state->get<CStringLength>();
Modified: cfe/trunk/lib/StaticAnalyzer/Core/BasicStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BasicStore.cpp?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BasicStore.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BasicStore.cpp Mon May 2 14:42:42 2011
@@ -49,11 +49,11 @@
SVal Retrieve(Store store, Loc loc, QualType T = QualType());
StoreRef invalidateRegion(Store store, const MemRegion *R, const Expr *E,
- unsigned Count, InvalidatedSymbols *IS);
+ unsigned Count, InvalidatedSymbols &IS);
StoreRef invalidateRegions(Store store, const MemRegion * const *Begin,
const MemRegion * const *End, const Expr *E,
- unsigned Count, InvalidatedSymbols *IS,
+ unsigned Count, InvalidatedSymbols &IS,
bool invalidateGlobals,
InvalidatedRegions *Regions);
@@ -538,7 +538,7 @@
const MemRegion * const *I,
const MemRegion * const *End,
const Expr *E, unsigned Count,
- InvalidatedSymbols *IS,
+ InvalidatedSymbols &IS,
bool invalidateGlobals,
InvalidatedRegions *Regions) {
StoreRef newStore(store, *this);
@@ -587,18 +587,16 @@
const MemRegion *R,
const Expr *E,
unsigned Count,
- InvalidatedSymbols *IS) {
+ InvalidatedSymbols &IS) {
R = R->StripCasts();
if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
return StoreRef(store, *this);
- if (IS) {
- BindingsTy B = GetBindings(store);
- if (BindingsTy::data_type *Val = B.lookup(R)) {
- if (SymbolRef Sym = Val->getAsSymbol())
- IS->insert(Sym);
- }
+ BindingsTy B = GetBindings(store);
+ if (BindingsTy::data_type *Val = B.lookup(R)) {
+ if (SymbolRef Sym = Val->getAsSymbol())
+ IS.insert(Sym);
}
QualType T = cast<TypedRegion>(R)->getValueType();
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp Mon May 2 14:42:42 2011
@@ -2494,6 +2494,23 @@
return RetTy;
}
+
+// HACK: Symbols that have ref-count state that are referenced directly
+// (not as structure or array elements, or via bindings) by an argument
+// should not have their ref-count state stripped after we have
+// done an invalidation pass.
+//
+// FIXME: This is a global to currently share between CFRefCount and
+// RetainReleaseChecker. Eventually all functionality in CFRefCount should
+// be migrated to RetainReleaseChecker, and we can make this a non-global.
+llvm::DenseSet<SymbolRef> WhitelistedSymbols;
+namespace {
+struct ResetWhiteList {
+ ResetWhiteList() {}
+ ~ResetWhiteList() { WhitelistedSymbols.clear(); }
+};
+}
+
void CFRefCount::evalSummary(ExplodedNodeSet& Dst,
ExprEngine& Eng,
StmtNodeBuilder& Builder,
@@ -2510,12 +2527,9 @@
SymbolRef ErrorSym = 0;
llvm::SmallVector<const MemRegion*, 10> RegionsToInvalidate;
-
- // HACK: Symbols that have ref-count state that are referenced directly
- // (not as structure or array elements, or via bindings) by an argument
- // should not have their ref-count state stripped after we have
- // done an invalidation pass.
- llvm::DenseSet<SymbolRef> WhitelistedSymbols;
+
+ // Use RAII to make sure the whitelist is properly cleared.
+ ResetWhiteList resetWhiteList;
// Invalidate all instance variables of the receiver of a message.
// FIXME: We should be able to do better with inter-procedural analysis.
@@ -2624,21 +2638,13 @@
// NOTE: Even if RegionsToInvalidate is empty, we must still invalidate
// global variables.
+ // NOTE: RetainReleaseChecker handles the actual invalidation of symbols.
state = state->invalidateRegions(RegionsToInvalidate.data(),
RegionsToInvalidate.data() +
RegionsToInvalidate.size(),
Ex, Count, &IS,
/* invalidateGlobals = */ true);
- for (StoreManager::InvalidatedSymbols::iterator I = IS.begin(),
- E = IS.end(); I!=E; ++I) {
- SymbolRef sym = *I;
- if (WhitelistedSymbols.count(sym))
- continue;
- // Remove any existing reference-count binding.
- state = state->remove<RefBindings>(*I);
- }
-
// Evaluate the effect on the message receiver.
if (!ErrorRange.isValid() && Receiver) {
SymbolRef Sym = Receiver.getSValAsScalarOrLoc(state).getAsLocSymbol();
@@ -3418,12 +3424,43 @@
namespace {
class RetainReleaseChecker
- : public Checker< check::PostStmt<BlockExpr> > {
+ : public Checker< check::PostStmt<BlockExpr>, check::RegionChanges > {
public:
+ bool wantsRegionUpdate;
+
+ RetainReleaseChecker() : wantsRegionUpdate(true) {}
+
+
void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
+ const GRState *checkRegionChanges(const GRState *state,
+ const StoreManager::InvalidatedSymbols *invalidated,
+ const MemRegion * const *begin,
+ const MemRegion * const *end) const;
+
+ bool wantsRegionChangeUpdate(const GRState *state) const {
+ return wantsRegionUpdate;
+ }
};
} // end anonymous namespace
+const GRState *
+RetainReleaseChecker::checkRegionChanges(const GRState *state,
+ const StoreManager::InvalidatedSymbols *invalidated,
+ const MemRegion * const *begin,
+ const MemRegion * const *end) const {
+ if (!invalidated)
+ return state;
+
+ for (StoreManager::InvalidatedSymbols::const_iterator I=invalidated->begin(),
+ E = invalidated->end(); I!=E; ++I) {
+ SymbolRef sym = *I;
+ if (WhitelistedSymbols.count(sym))
+ continue;
+ // Remove any existing reference-count binding.
+ state = state->remove<RefBindings>(sym);
+ }
+ return state;
+}
void RetainReleaseChecker::checkPostStmt(const BlockExpr *BE,
CheckerContext &C) const {
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp Mon May 2 14:42:42 2011
@@ -345,6 +345,7 @@
/// \brief Run checkers for region changes.
const GRState *
CheckerManager::runCheckersForRegionChanges(const GRState *state,
+ const StoreManager::InvalidatedSymbols *invalidated,
const MemRegion * const *Begin,
const MemRegion * const *End) {
for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i) {
@@ -352,7 +353,7 @@
// bail out.
if (!state)
return NULL;
- state = RegionChangesCheckers[i].CheckFn(state, Begin, End);
+ state = RegionChangesCheckers[i].CheckFn(state, invalidated, Begin, End);
}
return state;
}
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon May 2 14:42:42 2011
@@ -179,9 +179,11 @@
const GRState *
ExprEngine::processRegionChanges(const GRState *state,
- const MemRegion * const *Begin,
- const MemRegion * const *End) {
- return getCheckerManager().runCheckersForRegionChanges(state, Begin, End);
+ const StoreManager::InvalidatedSymbols *invalidated,
+ const MemRegion * const *Begin,
+ const MemRegion * const *End) {
+ return getCheckerManager().runCheckersForRegionChanges(state, invalidated,
+ Begin, End);
}
void ExprEngine::processEndWorklist(bool hasWorkRemaining) {
Modified: cfe/trunk/lib/StaticAnalyzer/Core/FlatStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/FlatStore.cpp?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/FlatStore.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/FlatStore.cpp Mon May 2 14:42:42 2011
@@ -59,7 +59,7 @@
StoreRef invalidateRegions(Store store, const MemRegion * const *I,
const MemRegion * const *E, const Expr *Ex,
- unsigned Count, InvalidatedSymbols *IS,
+ unsigned Count, InvalidatedSymbols &IS,
bool invalidateGlobals,
InvalidatedRegions *Regions);
@@ -175,7 +175,7 @@
const MemRegion * const *I,
const MemRegion * const *E,
const Expr *Ex, unsigned Count,
- InvalidatedSymbols *IS,
+ InvalidatedSymbols &IS,
bool invalidateGlobals,
InvalidatedRegions *Regions) {
assert(false && "Not implemented");
Modified: cfe/trunk/lib/StaticAnalyzer/Core/GRState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/GRState.cpp?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/GRState.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/GRState.cpp Mon May 2 14:42:42 2011
@@ -141,6 +141,20 @@
const Expr *E, unsigned Count,
StoreManager::InvalidatedSymbols *IS,
bool invalidateGlobals) const {
+ if (!IS) {
+ StoreManager::InvalidatedSymbols invalidated;
+ return invalidateRegionsImpl(Begin, End, E, Count,
+ invalidated, invalidateGlobals);
+ }
+ return invalidateRegionsImpl(Begin, End, E, Count, *IS, invalidateGlobals);
+}
+
+const GRState *
+GRState::invalidateRegionsImpl(const MemRegion * const *Begin,
+ const MemRegion * const *End,
+ const Expr *E, unsigned Count,
+ StoreManager::InvalidatedSymbols &IS,
+ bool invalidateGlobals) const {
GRStateManager &Mgr = getStateManager();
SubEngine* Eng = Mgr.getOwningEngine();
@@ -150,7 +164,7 @@
= Mgr.StoreMgr->invalidateRegions(getStore(), Begin, End, E, Count, IS,
invalidateGlobals, &Regions);
const GRState *newState = makeWithStore(newStore);
- return Eng->processRegionChanges(newState,
+ return Eng->processRegionChanges(newState, &IS,
&Regions.front(),
&Regions.back()+1);
}
Modified: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp Mon May 2 14:42:42 2011
@@ -240,7 +240,7 @@
const MemRegion * const *Begin,
const MemRegion * const *End,
const Expr *E, unsigned Count,
- InvalidatedSymbols *IS,
+ InvalidatedSymbols &IS,
bool invalidateGlobals,
InvalidatedRegions *Regions);
@@ -586,14 +586,14 @@
{
const Expr *Ex;
unsigned Count;
- StoreManager::InvalidatedSymbols *IS;
+ StoreManager::InvalidatedSymbols &IS;
StoreManager::InvalidatedRegions *Regions;
public:
invalidateRegionsWorker(RegionStoreManager &rm,
GRStateManager &stateMgr,
RegionBindings b,
const Expr *ex, unsigned count,
- StoreManager::InvalidatedSymbols *is,
+ StoreManager::InvalidatedSymbols &is,
StoreManager::InvalidatedRegions *r,
bool includeGlobals)
: ClusterAnalysis<invalidateRegionsWorker>(rm, stateMgr, b, includeGlobals),
@@ -609,9 +609,8 @@
void invalidateRegionsWorker::VisitBinding(SVal V) {
// A symbol? Mark it touched by the invalidation.
- if (IS)
- if (SymbolRef Sym = V.getAsSymbol())
- IS->insert(Sym);
+ if (SymbolRef Sym = V.getAsSymbol())
+ IS.insert(Sym);
if (const MemRegion *R = V.getAsRegion()) {
AddToWorkList(R);
@@ -648,11 +647,9 @@
}
void invalidateRegionsWorker::VisitBaseRegion(const MemRegion *baseR) {
- if (IS) {
- // Symbolic region? Mark that symbol touched by the invalidation.
- if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR))
- IS->insert(SR->getSymbol());
- }
+ // Symbolic region? Mark that symbol touched by the invalidation.
+ if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR))
+ IS.insert(SR->getSymbol());
// BlockDataRegion? If so, invalidate captured variables that are passed
// by reference.
@@ -724,7 +721,7 @@
const MemRegion * const *I,
const MemRegion * const *E,
const Expr *Ex, unsigned Count,
- InvalidatedSymbols *IS,
+ InvalidatedSymbols &IS,
bool invalidateGlobals,
InvalidatedRegions *Regions) {
invalidateRegionsWorker W(*this, StateMgr,
Modified: cfe/trunk/test/Analysis/retain-release.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/retain-release.m?rev=130711&r1=130710&r2=130711&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/retain-release.m (original)
+++ cfe/trunk/test/Analysis/retain-release.m Mon May 2 14:42:42 2011
@@ -280,7 +280,7 @@
CFRelease(date);
CFDateGetAbsoluteTime(date); // no-warning
CFRelease(date);
- t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}}
+ t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}}
return t;
}
@@ -291,7 +291,7 @@
CFRelease(date);
CFDateGetAbsoluteTime(date); // no-warning
[((NSDate*) date) release];
- t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}}
+ t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}}
return t;
}
Added: cfe/trunk/test/Analysis/retain-release.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/retain-release.mm?rev=130711&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/retain-release.mm (added)
+++ cfe/trunk/test/Analysis/retain-release.mm Mon May 2 14:42:42 2011
@@ -0,0 +1,284 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=region -fblocks -verify %s
+
+#if __has_feature(attribute_ns_returns_retained)
+#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
+#endif
+#if __has_feature(attribute_cf_returns_retained)
+#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
+#endif
+#if __has_feature(attribute_ns_returns_not_retained)
+#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
+#endif
+#if __has_feature(attribute_cf_returns_not_retained)
+#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
+#endif
+#if __has_feature(attribute_ns_consumes_self)
+#define NS_CONSUMES_SELF __attribute__((ns_consumes_self))
+#endif
+#if __has_feature(attribute_ns_consumed)
+#define NS_CONSUMED __attribute__((ns_consumed))
+#endif
+#if __has_feature(attribute_cf_consumed)
+#define CF_CONSUMED __attribute__((cf_consumed))
+#endif
+
+//===----------------------------------------------------------------------===//
+// The following code is reduced using delta-debugging from Mac OS X headers:
+//
+// #include <Cocoa/Cocoa.h>
+// #include <CoreFoundation/CoreFoundation.h>
+// #include <DiskArbitration/DiskArbitration.h>
+// #include <QuartzCore/QuartzCore.h>
+// #include <Quartz/Quartz.h>
+// #include <IOKit/IOKitLib.h>
+//
+// It includes the basic definitions for the test cases below.
+//===----------------------------------------------------------------------===//
+
+typedef unsigned int __darwin_natural_t;
+typedef unsigned long uintptr_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+typedef unsigned int UInt32;
+typedef signed long CFIndex;
+typedef struct {
+ CFIndex location;
+ CFIndex length;
+} CFRange;
+static __inline__ __attribute__((always_inline)) CFRange CFRangeMake(CFIndex loc, CFIndex len) {
+ CFRange range;
+ range.location = loc;
+ range.length = len;
+ return range;
+}
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+extern const CFAllocatorRef kCFAllocatorDefault;
+extern CFTypeRef CFRetain(CFTypeRef cf);
+extern void CFRelease(CFTypeRef cf);
+typedef struct {
+}
+CFArrayCallBacks;
+extern const CFArrayCallBacks kCFTypeArrayCallBacks;
+typedef const struct __CFArray * CFArrayRef;
+typedef struct __CFArray * CFMutableArrayRef;
+extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
+extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
+extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value);
+typedef struct {
+}
+CFDictionaryKeyCallBacks;
+extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks;
+typedef struct {
+}
+CFDictionaryValueCallBacks;
+extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks;
+typedef const struct __CFDictionary * CFDictionaryRef;
+typedef struct __CFDictionary * CFMutableDictionaryRef;
+extern CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks);
+typedef UInt32 CFStringEncoding;
+enum {
+kCFStringEncodingMacRoman = 0, kCFStringEncodingWindowsLatin1 = 0x0500, kCFStringEncodingISOLatin1 = 0x0201, kCFStringEncodingNextStepLatin = 0x0B01, kCFStringEncodingASCII = 0x0600, kCFStringEncodingUnicode = 0x0100, kCFStringEncodingUTF8 = 0x08000100, kCFStringEncodingNonLossyASCII = 0x0BFF , kCFStringEncodingUTF16 = 0x0100, kCFStringEncodingUTF16BE = 0x10000100, kCFStringEncodingUTF16LE = 0x14000100, kCFStringEncodingUTF32 = 0x0c000100, kCFStringEncodingUTF32BE = 0x18000100, kCFStringEncodingUTF32LE = 0x1c000100 };
+extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
+typedef double CFTimeInterval;
+typedef CFTimeInterval CFAbsoluteTime;
+extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
+typedef const struct __CFDate * CFDateRef;
+extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
+extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate);
+typedef __darwin_natural_t natural_t;
+typedef natural_t mach_port_name_t;
+typedef mach_port_name_t mach_port_t;
+typedef int kern_return_t;
+typedef kern_return_t mach_error_t;
+enum {
+kCFNumberSInt8Type = 1, kCFNumberSInt16Type = 2, kCFNumberSInt32Type = 3, kCFNumberSInt64Type = 4, kCFNumberFloat32Type = 5, kCFNumberFloat64Type = 6, kCFNumberCharType = 7, kCFNumberShortType = 8, kCFNumberIntType = 9, kCFNumberLongType = 10, kCFNumberLongLongType = 11, kCFNumberFloatType = 12, kCFNumberDoubleType = 13, kCFNumberCFIndexType = 14, kCFNumberNSIntegerType = 15, kCFNumberCGFloatType = 16, kCFNumberMaxType = 16 };
+typedef CFIndex CFNumberType;
+typedef const struct __CFNumber * CFNumberRef;
+extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
+typedef const struct __CFAttributedString *CFAttributedStringRef;
+typedef struct __CFAttributedString *CFMutableAttributedStringRef;
+extern CFAttributedStringRef CFAttributedStringCreate(CFAllocatorRef alloc, CFStringRef str, CFDictionaryRef attributes) ;
+extern CFMutableAttributedStringRef CFAttributedStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFAttributedStringRef aStr) ;
+extern void CFAttributedStringSetAttribute(CFMutableAttributedStringRef aStr, CFRange range, CFStringRef attrName, CFTypeRef value) ;
+typedef signed char BOOL;
+typedef unsigned long NSUInteger;
+ at class NSString, Protocol;
+extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
+typedef struct _NSZone NSZone;
+ at class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+ at protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (id)retain;
+- (oneway void)release;
+- (id)autorelease;
+ at end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone;
+ at end @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone;
+ at end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder;
+ at end
+ at interface NSObject <NSObject> {}
++ (id)allocWithZone:(NSZone *)zone;
++ (id)alloc;
+- (void)dealloc;
+ at end
+ at interface NSObject (NSCoderMethods)
+- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder;
+ at end
+extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
+typedef struct {
+}
+NSFastEnumerationState;
+ at protocol NSFastEnumeration - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
+ at end @class NSString, NSDictionary;
+ at interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value;
+ at end @interface NSNumber : NSValue - (char)charValue;
+- (id)initWithInt:(int)value;
+ at end @class NSString;
+ at interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count;
+ at end @interface NSArray (NSArrayCreation) + (id)array;
+ at end @interface NSAutoreleasePool : NSObject {
+}
+- (void)drain;
+ at end extern NSString * const NSBundleDidLoadNotification;
+typedef double NSTimeInterval;
+ at interface NSDate : NSObject <NSCopying, NSCoding> - (NSTimeInterval)timeIntervalSinceReferenceDate;
+ at end typedef unsigned short unichar;
+ at interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length;
+- ( const char *)UTF8String;
+- (id)initWithUTF8String:(const char *)nullTerminatedCString;
++ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
+ at end @class NSString, NSURL, NSError;
+ at interface NSData : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length;
++ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length;
++ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b;
+ at end @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary;
+ at interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count;
+ at end @interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey;
+- (void)setObject:(id)anObject forKey:(id)aKey;
+ at end @interface NSMutableDictionary (NSMutableDictionaryCreation) + (id)dictionaryWithCapacity:(NSUInteger)numItems;
+ at end typedef double CGFloat;
+struct CGSize {
+};
+typedef struct CGSize CGSize;
+struct CGRect {
+};
+typedef struct CGRect CGRect;
+typedef mach_port_t io_object_t;
+typedef char io_name_t[128];
+typedef io_object_t io_iterator_t;
+typedef io_object_t io_service_t;
+typedef struct IONotificationPort * IONotificationPortRef;
+typedef void (*IOServiceMatchingCallback)( void * refcon, io_iterator_t iterator );
+io_service_t IOServiceGetMatchingService( mach_port_t masterPort, CFDictionaryRef matching );
+kern_return_t IOServiceGetMatchingServices( mach_port_t masterPort, CFDictionaryRef matching, io_iterator_t * existing );
+kern_return_t IOServiceAddNotification( mach_port_t masterPort, const io_name_t notificationType, CFDictionaryRef matching, mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) __attribute__((deprecated));
+kern_return_t IOServiceAddMatchingNotification( IONotificationPortRef notifyPort, const io_name_t notificationType, CFDictionaryRef matching, IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification );
+CFMutableDictionaryRef IOServiceMatching( const char * name );
+CFMutableDictionaryRef IOServiceNameMatching( const char * name );
+CFMutableDictionaryRef IOBSDNameMatching( mach_port_t masterPort, uint32_t options, const char * bsdName );
+CFMutableDictionaryRef IOOpenFirmwarePathMatching( mach_port_t masterPort, uint32_t options, const char * path );
+CFMutableDictionaryRef IORegistryEntryIDMatching( uint64_t entryID );
+typedef struct __DASession * DASessionRef;
+extern DASessionRef DASessionCreate( CFAllocatorRef allocator );
+typedef struct __DADisk * DADiskRef;
+extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name );
+extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media );
+extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk );
+extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk );
+ at interface NSTask : NSObject - (id)init;
+ at end typedef struct CGColorSpace *CGColorSpaceRef;
+typedef struct CGImage *CGImageRef;
+typedef struct CGLayer *CGLayerRef;
+ at interface NSResponder : NSObject <NSCoding> {
+}
+ at end @protocol NSAnimatablePropertyContainer - (id)animator;
+ at end extern NSString *NSAnimationTriggerOrderIn ;
+ at interface NSView : NSResponder <NSAnimatablePropertyContainer> {
+}
+ at end @protocol NSValidatedUserInterfaceItem - (SEL)action;
+ at end @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem;
+ at end @class NSDate, NSDictionary, NSError, NSException, NSNotification;
+ at interface NSApplication : NSResponder <NSUserInterfaceValidations> {
+}
+ at end enum {
+NSTerminateCancel = 0, NSTerminateNow = 1, NSTerminateLater = 2 };
+typedef NSUInteger NSApplicationTerminateReply;
+ at protocol NSApplicationDelegate <NSObject> @optional - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
+ at end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView;
+ at interface NSCell : NSObject <NSCopying, NSCoding> {
+}
+ at end @class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError;
+typedef struct {
+}
+CVTimeStamp;
+ at interface CIImage : NSObject <NSCoding, NSCopying> {
+}
+typedef int CIFormat;
+ at end enum {
+kDAReturnSuccess = 0, kDAReturnError = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01, kDAReturnBusy = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02, kDAReturnBadArgument = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03, kDAReturnExclusiveAccess = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04, kDAReturnNoResources = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05, kDAReturnNotFound = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06, kDAReturnNotMounted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07, kDAReturnNotPermitted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08, kDAReturnNotPrivileged = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09, kDAReturnNotReady = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A, kDAReturnNotWritable = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B, kDAReturnUnsupported = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0C };
+typedef mach_error_t DAReturn;
+typedef const struct __DADissenter * DADissenterRef;
+extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string );
+ at interface CIContext: NSObject {
+}
+- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r;
+- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs;
+- (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d;
+ at end extern NSString* const QCRendererEventKey;
+ at protocol QCCompositionRenderer - (NSDictionary*) attributes;
+ at end @interface QCRenderer : NSObject <QCCompositionRenderer> {
+}
+- (id) createSnapshotImageOfType:(NSString*)type;
+ at end extern NSString* const QCViewDidStartRenderingNotification;
+ at interface QCView : NSView <QCCompositionRenderer> {
+}
+- (id) createSnapshotImageOfType:(NSString*)type;
+ at end enum {
+ICEXIFOrientation1 = 1, ICEXIFOrientation2 = 2, ICEXIFOrientation3 = 3, ICEXIFOrientation4 = 4, ICEXIFOrientation5 = 5, ICEXIFOrientation6 = 6, ICEXIFOrientation7 = 7, ICEXIFOrientation8 = 8, };
+ at class ICDevice;
+ at protocol ICDeviceDelegate <NSObject> @required - (void)didRemoveDevice:(ICDevice*)device;
+ at end extern NSString *const ICScannerStatusWarmingUp;
+ at class ICScannerDevice;
+ at protocol ICScannerDeviceDelegate <ICDeviceDelegate> @optional - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner;
+ at end
+
+typedef long unsigned int __darwin_size_t;
+typedef __darwin_size_t size_t;
+typedef unsigned long CFTypeID;
+struct CGPoint {
+ CGFloat x;
+ CGFloat y;
+};
+typedef struct CGPoint CGPoint;
+typedef struct CGGradient *CGGradientRef;
+typedef uint32_t CGGradientDrawingOptions;
+extern CFTypeID CGGradientGetTypeID(void);
+extern CGGradientRef CGGradientCreateWithColorComponents(CGColorSpaceRef
+ space, const CGFloat components[], const CGFloat locations[], size_t count);
+extern CGGradientRef CGGradientCreateWithColors(CGColorSpaceRef space,
+ CFArrayRef colors, const CGFloat locations[]);
+extern CGGradientRef CGGradientRetain(CGGradientRef gradient);
+extern void CGGradientRelease(CGGradientRef gradient);
+typedef struct CGContext *CGContextRef;
+extern void CGContextDrawLinearGradient(CGContextRef context,
+ CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint,
+ CGGradientDrawingOptions options);
+extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void);
+
+//===----------------------------------------------------------------------===//
+// Test cases.
+//===----------------------------------------------------------------------===//
+
+class SmartPointer {
+ id x;
+public:
+ SmartPointer(id x) : x(x) {}
+ ~SmartPointer() { [x release]; }
+};
+
+void test_smartpointer_1() {
+ id x = [[NSObject alloc] init]; // no-warning
+ SmartPointer foo(x);
+}
+
More information about the cfe-commits
mailing list