[analyzer] Move the knowledge of whether or not GC is enabled for the current analysis from CFRefCount to ExprEngine.

Remove TransferFuncs from ExprEngine and AnalysisConsumer.

Demote RetainReleaseChecker to a regular checker, and give it the name osx.cocoa.RetainCount (class name change coming shortly). Update tests accordingly.

llvm-svn: 138998
This commit is contained in:
Jordy Rose 2011-09-02 05:55:19 +00:00
parent 94ce535647
commit c49ec53e29
30 changed files with 161 additions and 171 deletions

View File

@ -103,6 +103,10 @@ public:
return getSValBuilder().getSymbolManager();
}
bool isObjCGCEnabled() {
return Eng.isObjCGCEnabled();
}
ExplodedNode *generateNode(bool autoTransition = true) {
assert(statement && "Only transitions with statements currently supported");
ExplodedNode *N = generateNodeImpl(statement, getState(), false,

View File

@ -74,16 +74,17 @@ class ExprEngine : public SubEngine {
// Obj-C Selectors.
Selector* NSExceptionInstanceRaiseSelectors;
Selector RaiseSel;
/// Whether or not GC is enabled in this analysis.
bool ObjCGCEnabled;
/// The BugReporter associated with this engine. It is important that
/// this object be placed at the very end of member variables so that its
/// destructor is called before the rest of the ExprEngine is destroyed.
GRBugReporter BR;
llvm::OwningPtr<TransferFuncs> TF;
public:
ExprEngine(AnalysisManager &mgr, TransferFuncs *tf);
ExprEngine(AnalysisManager &mgr, bool gcEnabled);
~ExprEngine();
@ -111,14 +112,11 @@ public:
SValBuilder &getSValBuilder() { return svalBuilder; }
TransferFuncs& getTF() { return *TF; }
BugReporter& getBugReporter() { return BR; }
StmtNodeBuilder &getBuilder() { assert(Builder); return *Builder; }
// FIXME: Remove once TransferFuncs is no longer referenced.
void setTransferFunction(TransferFuncs* tf);
bool isObjCGCEnabled() { return ObjCGCEnabled; }
/// ViewGraph - Visualize the ExplodedGraph created by executing the
/// simulation.

View File

@ -311,6 +311,10 @@ def NSErrorChecker : Checker<"NSError">,
HelpText<"Check usage of NSError** parameters">,
DescFile<"NSErrorChecker.cpp">;
def RetainCountChecker : Checker<"RetainCount">,
HelpText<"Check for leaks and improper reference count management">,
DescFile<"RetainCountChecker.cpp">;
} // end "cocoa"
let ParentPackage = CocoaExperimental in {

View File

@ -2357,11 +2357,8 @@ class RetainReleaseChecker
mutable SummaryLogTy SummaryLog;
mutable bool ShouldResetSummaryLog;
LangOptions::GCMode GCMode;
public:
RetainReleaseChecker()
: ShouldResetSummaryLog(false), GCMode(LangOptions::HybridGC) {}
RetainReleaseChecker() : ShouldResetSummaryLog(false) {}
virtual ~RetainReleaseChecker() {
DeleteContainerSeconds(DeadSymbolTags);
@ -2403,41 +2400,17 @@ public:
ShouldResetSummaryLog = !SummaryLog.empty();
}
void setGCMode(LangOptions::GCMode newGC) {
// FIXME: This is definitely not const behavior; its intended use is to
// set the GC mode for the entire coming code body. This setting will
// most likely live somewhere else in the future.
assert(newGC != LangOptions::HybridGC && "Analysis requires GC on or off.");
GCMode = newGC;
}
bool isGCEnabled() const {
switch (GCMode) {
case LangOptions::HybridGC:
llvm_unreachable("GC mode not set yet!");
case LangOptions::NonGC:
return false;
case LangOptions::GCOnly:
return true;
}
llvm_unreachable("Invalid/unknown GC mode.");
}
bool isARCorGCEnabled(ASTContext &Ctx) const {
return isGCEnabled() || Ctx.getLangOptions().ObjCAutoRefCount;
}
CFRefBug *getLeakWithinFunctionBug(ASTContext &Ctx) const {
if (isGCEnabled()) {
CFRefBug *getLeakWithinFunctionBug(const LangOptions &LOpts,
bool GCEnabled) const {
if (GCEnabled) {
if (!leakWithinFunctionGC)
leakWithinFunctionGC.reset(new LeakWithinFunction("Leak of object when "
"using garbage "
"collection"));
return &*leakWithinFunctionGC;
return leakWithinFunctionGC.get();
} else {
if (!leakWithinFunction) {
if (Ctx.getLangOptions().getGCMode() == LangOptions::HybridGC) {
if (LOpts.getGCMode() == LangOptions::HybridGC) {
leakWithinFunction.reset(new LeakWithinFunction("Leak of object when "
"not using garbage "
"collection (GC) in "
@ -2447,19 +2420,19 @@ public:
leakWithinFunction.reset(new LeakWithinFunction("Leak"));
}
}
return &*leakWithinFunction;
return leakWithinFunction.get();
}
}
CFRefBug *getLeakAtReturnBug(ASTContext &Ctx) const {
if (isGCEnabled()) {
CFRefBug *getLeakAtReturnBug(const LangOptions &LOpts, bool GCEnabled) const {
if (GCEnabled) {
if (!leakAtReturnGC)
leakAtReturnGC.reset(new LeakAtReturn("Leak of returned object when "
"using garbage collection"));
return &*leakAtReturnGC;
return leakAtReturnGC.get();
} else {
if (!leakAtReturn) {
if (Ctx.getLangOptions().getGCMode() == LangOptions::HybridGC) {
if (LOpts.getGCMode() == LangOptions::HybridGC) {
leakAtReturn.reset(new LeakAtReturn("Leak of returned object when "
"not using garbage collection "
"(GC) in dual GC/non-GC code"));
@ -2467,26 +2440,34 @@ public:
leakAtReturn.reset(new LeakAtReturn("Leak of returned object"));
}
}
return &*leakAtReturn;
return leakAtReturn.get();
}
}
RetainSummaryManager &getSummaryManager(ASTContext &Ctx) const {
if (isGCEnabled()) {
if (!SummariesGC) {
bool ARCEnabled = (bool)Ctx.getLangOptions().ObjCAutoRefCount;
RetainSummaryManager &getSummaryManager(ASTContext &Ctx,
bool GCEnabled) const {
// FIXME: We don't support ARC being turned on and off during one analysis.
// (nor, for that matter, do we support changing ASTContexts)
bool ARCEnabled = (bool)Ctx.getLangOptions().ObjCAutoRefCount;
if (GCEnabled) {
if (!SummariesGC)
SummariesGC.reset(new RetainSummaryManager(Ctx, true, ARCEnabled));
}
else
assert(SummariesGC->isARCEnabled() == ARCEnabled);
return *SummariesGC;
} else {
if (!Summaries) {
bool ARCEnabled = (bool)Ctx.getLangOptions().ObjCAutoRefCount;
if (!Summaries)
Summaries.reset(new RetainSummaryManager(Ctx, false, ARCEnabled));
}
else
assert(Summaries->isARCEnabled() == ARCEnabled);
return *Summaries;
}
}
RetainSummaryManager &getSummaryManager(CheckerContext &C) const {
return getSummaryManager(C.getASTContext(), C.isObjCGCEnabled());
}
void printState(raw_ostream &Out, const ProgramState *State,
const char *NL, const char *Sep) const;
@ -2524,8 +2505,8 @@ public:
void checkEndPath(EndOfFunctionNodeBuilder &Builder, ExprEngine &Eng) const;
const ProgramState *updateSymbol(const ProgramState *state, SymbolRef sym,
RefVal V, ArgEffect E,
RefVal::Kind &hasErr) const;
RefVal V, ArgEffect E, RefVal::Kind &hasErr,
CheckerContext &C) const;
void processNonLeakError(const ProgramState *St, SourceRange ErrorRange,
RefVal::Kind ErrorKind, SymbolRef Sym,
@ -2730,7 +2711,7 @@ void RetainReleaseChecker::checkPostStmt(const CastExpr *CE,
return;
RefVal::Kind hasErr = (RefVal::Kind) 0;
state = updateSymbol(state, Sym, *T, AE, hasErr);
state = updateSymbol(state, Sym, *T, AE, hasErr, C);
if (hasErr) {
// FIXME: If we get an error during a bridge cast, should we report it?
@ -2748,7 +2729,7 @@ void RetainReleaseChecker::checkPostStmt(const CallExpr *CE,
const Expr *Callee = CE->getCallee();
SVal L = state->getSVal(Callee);
RetainSummaryManager &Summaries = getSummaryManager(C.getASTContext());
RetainSummaryManager &Summaries = getSummaryManager(C);
RetainSummary *Summ = 0;
// FIXME: Better support for blocks. For now we stop tracking anything
@ -2776,7 +2757,7 @@ void RetainReleaseChecker::checkPostStmt(const CXXConstructExpr *CE,
if (!Ctor)
return;
RetainSummaryManager &Summaries = getSummaryManager(C.getASTContext());
RetainSummaryManager &Summaries = getSummaryManager(C);
RetainSummary *Summ = Summaries.getSummary(Ctor);
// If we didn't get a summary, this constructor doesn't affect retain counts.
@ -2792,7 +2773,7 @@ void RetainReleaseChecker::checkPostObjCMessage(const ObjCMessage &Msg,
const ProgramState *state = C.getState();
ExplodedNode *Pred = C.getPredecessor();
RetainSummaryManager &Summaries = getSummaryManager(C.getASTContext());
RetainSummaryManager &Summaries = getSummaryManager(C);
RetainSummary *Summ;
if (Msg.isInstanceMessage()) {
@ -2824,7 +2805,7 @@ void RetainReleaseChecker::checkSummary(const RetainSummary &Summ,
if (SymbolRef Sym = V.getAsLocSymbol()) {
if (RefBindings::data_type *T = state->get<RefBindings>(Sym)) {
state = updateSymbol(state, Sym, *T, Summ.getArg(idx), hasErr);
state = updateSymbol(state, Sym, *T, Summ.getArg(idx), hasErr, C);
if (hasErr) {
ErrorRange = CallOrMsg.getArgSourceRange(idx);
ErrorSym = Sym;
@ -2842,7 +2823,8 @@ void RetainReleaseChecker::checkSummary(const RetainSummary &Summ,
if (SymbolRef Sym = Receiver.getAsLocSymbol()) {
if (const RefVal *T = state->get<RefBindings>(Sym)) {
ReceiverIsTracked = true;
state = updateSymbol(state, Sym, *T, Summ.getReceiverEffect(), hasErr);
state = updateSymbol(state, Sym, *T, Summ.getReceiverEffect(),
hasErr, C);
if (hasErr) {
ErrorRange = CallOrMsg.getReceiverSourceRange();
ErrorSym = Sym;
@ -2862,7 +2844,7 @@ void RetainReleaseChecker::checkSummary(const RetainSummary &Summ,
if (RE.getKind() == RetEffect::OwnedWhenTrackedReceiver) {
if (ReceiverIsTracked)
RE = getSummaryManager(C.getASTContext()).getObjAllocRetEffect();
RE = getSummaryManager(C).getObjAllocRetEffect();
else
RE = RetEffect::MakeNoRet();
}
@ -2940,21 +2922,24 @@ void RetainReleaseChecker::checkSummary(const RetainSummary &Summ,
const ProgramState *
RetainReleaseChecker::updateSymbol(const ProgramState *state, SymbolRef sym,
RefVal V, ArgEffect E,
RefVal::Kind &hasErr) const {
RefVal V, ArgEffect E, RefVal::Kind &hasErr,
CheckerContext &C) const {
// In GC mode [... release] and [... retain] do nothing.
ASTContext &Ctx = state->getStateManager().getContext();
bool IgnoreRetainMsg = C.isObjCGCEnabled();
if (!IgnoreRetainMsg)
IgnoreRetainMsg = (bool)C.getASTContext().getLangOptions().ObjCAutoRefCount;
switch (E) {
default: break;
case IncRefMsg: E = isARCorGCEnabled(Ctx) ? DoNothing : IncRef; break;
case DecRefMsg: E = isARCorGCEnabled(Ctx) ? DoNothing : DecRef; break;
case MakeCollectable: E = isGCEnabled() ? DecRef : DoNothing; break;
case NewAutoreleasePool: E = isGCEnabled() ? DoNothing :
NewAutoreleasePool; break;
case IncRefMsg: E = IgnoreRetainMsg ? DoNothing : IncRef; break;
case DecRefMsg: E = IgnoreRetainMsg ? DoNothing : DecRef; break;
case MakeCollectable: E = C.isObjCGCEnabled() ? DecRef : DoNothing; break;
case NewAutoreleasePool: E = C.isObjCGCEnabled() ? DoNothing :
NewAutoreleasePool; break;
}
// Handle all use-after-releases.
if (!isGCEnabled() && V.getKind() == RefVal::Released) {
if (!C.isObjCGCEnabled() && V.getKind() == RefVal::Released) {
V = V ^ RefVal::ErrorUseAfterRelease;
hasErr = V.getKind();
return state->set<RefBindings>(sym, V);
@ -2969,7 +2954,7 @@ RetainReleaseChecker::updateSymbol(const ProgramState *state, SymbolRef sym,
case Dealloc:
// Any use of -dealloc in GC is *bad*.
if (isGCEnabled()) {
if (C.isObjCGCEnabled()) {
V = V ^ RefVal::ErrorDeallocGC;
hasErr = V.getKind();
break;
@ -2992,7 +2977,7 @@ RetainReleaseChecker::updateSymbol(const ProgramState *state, SymbolRef sym,
break;
case NewAutoreleasePool:
assert(!isGCEnabled());
assert(!C.isObjCGCEnabled());
return state->add<AutoreleaseStack>(sym);
case MayEscape:
@ -3007,7 +2992,7 @@ RetainReleaseChecker::updateSymbol(const ProgramState *state, SymbolRef sym,
return state;
case Autorelease:
if (isGCEnabled())
if (C.isObjCGCEnabled())
return state;
// Update the autorelease counts.
@ -3029,7 +3014,7 @@ RetainReleaseChecker::updateSymbol(const ProgramState *state, SymbolRef sym,
break;
case RefVal::Released:
// Non-GC cases are handled above.
assert(isGCEnabled());
assert(C.isObjCGCEnabled());
V = (V ^ RefVal::Owned) + 1;
break;
}
@ -3065,7 +3050,7 @@ RetainReleaseChecker::updateSymbol(const ProgramState *state, SymbolRef sym,
case RefVal::Released:
// Non-GC cases are handled above.
assert(isGCEnabled());
assert(C.isObjCGCEnabled());
V = V ^ RefVal::ErrorUseAfterRelease;
hasErr = V.getKind();
break;
@ -3113,7 +3098,8 @@ void RetainReleaseChecker::processNonLeakError(const ProgramState *St,
assert(BT);
CFRefReport *report = new CFRefReport(*BT, C.getASTContext().getLangOptions(),
isGCEnabled(), SummaryLog, N, Sym);
C.isObjCGCEnabled(), SummaryLog,
N, Sym);
report->addRange(ErrorRange);
C.EmitReport(report);
}
@ -3271,7 +3257,7 @@ void RetainReleaseChecker::checkPreStmt(const ReturnStmt *S,
X = *T;
// Consult the summary of the enclosing method.
RetainSummaryManager &Summaries = getSummaryManager(C.getASTContext());
RetainSummaryManager &Summaries = getSummaryManager(C);
const Decl *CD = &Pred->getCodeDecl();
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
@ -3301,7 +3287,7 @@ void RetainReleaseChecker::checkReturnWithRetEffect(const ReturnStmt *S,
if (X.isReturnedOwned() && X.getCount() == 0) {
if (RE.getKind() != RetEffect::NoRet) {
bool hasError = false;
if (isGCEnabled() && RE.getObjKind() == RetEffect::ObjC) {
if (C.isObjCGCEnabled() && RE.getObjKind() == RetEffect::ObjC) {
// Things are more complicated with garbage collection. If the
// returned object is suppose to be an Objective-C object, we have
// a leak (as the caller expects a GC'ed object) because no
@ -3327,11 +3313,12 @@ void RetainReleaseChecker::checkReturnWithRetEffect(const ReturnStmt *S,
ExplodedNode *N = Builder.generateNode(S, state, Pred,
&ReturnOwnLeakTag);
if (N) {
ASTContext &Ctx = C.getASTContext();
const LangOptions &LOpts = C.getASTContext().getLangOptions();
bool GCEnabled = C.isObjCGCEnabled();
CFRefReport *report =
new CFRefLeakReport(*getLeakAtReturnBug(Ctx), Ctx.getLangOptions(),
isGCEnabled(), SummaryLog, N, Sym,
C.getEngine());
new CFRefLeakReport(*getLeakAtReturnBug(LOpts, GCEnabled),
LOpts, GCEnabled, SummaryLog,
N, Sym, C.getEngine());
C.EmitReport(report);
}
}
@ -3353,8 +3340,8 @@ void RetainReleaseChecker::checkReturnWithRetEffect(const ReturnStmt *S,
CFRefReport *report =
new CFRefReport(*returnNotOwnedForOwned,
C.getASTContext().getLangOptions(), isGCEnabled(),
SummaryLog, N, Sym);
C.getASTContext().getLangOptions(),
C.isObjCGCEnabled(), SummaryLog, N, Sym);
C.EmitReport(report);
}
}
@ -3377,7 +3364,7 @@ RetainReleaseChecker::handleAutoreleaseCounts(const ProgramState *state,
if (!ACnt)
return std::make_pair(Pred, state);
assert(!isGCEnabled() && "Autorelease counts in GC mode?");
assert(!Eng.isObjCGCEnabled() && "Autorelease counts in GC mode?");
unsigned Cnt = V.getCount();
// FIXME: Handle sending 'autorelease' to already released object.
@ -3465,13 +3452,13 @@ RetainReleaseChecker::processLeaks(const ProgramState *state,
for (SmallVectorImpl<SymbolRef>::iterator
I = Leaked.begin(), E = Leaked.end(); I != E; ++I) {
ASTContext &Ctx = Eng.getContext();
CFRefBug *BT = Pred ? getLeakWithinFunctionBug(Ctx)
: getLeakAtReturnBug(Ctx);
const LangOptions &LOpts = Eng.getContext().getLangOptions();
bool GCEnabled = Eng.isObjCGCEnabled();
CFRefBug *BT = Pred ? getLeakWithinFunctionBug(LOpts, GCEnabled)
: getLeakAtReturnBug(LOpts, GCEnabled);
assert(BT && "BugType not initialized.");
const LangOptions &LOpts = Ctx.getLangOptions();
CFRefLeakReport *report = new CFRefLeakReport(*BT, LOpts, isGCEnabled(),
CFRefLeakReport *report = new CFRefLeakReport(*BT, LOpts, GCEnabled,
SummaryLog, N, *I, Eng);
Eng.getBugReporter().EmitReport(report);
}
@ -3638,10 +3625,24 @@ void CFRefCount::RegisterChecks(ExprEngine& Eng) {
RetainReleaseChecker *checker =
Eng.getCheckerManager().registerChecker<RetainReleaseChecker>();
assert(checker);
checker->setGCMode(GCEnabled ? LangOptions::GCOnly : LangOptions::NonGC);
//checker->setGCMode(GCEnabled ? LangOptions::GCOnly : LangOptions::NonGC);
}
TransferFuncs* ento::MakeCFRefCountTF(ASTContext &Ctx, bool GCEnabled,
const LangOptions& lopts) {
return new CFRefCount(Ctx, GCEnabled, lopts);
}
// FIXME: This will be unnecessary once RetainReleaseChecker is moved to
// the Checkers library (...and renamed to RetainCountChecker).
namespace clang {
namespace ento {
void registerRetainCountChecker(CheckerManager &Mgr);
}
}
void ento::registerRetainCountChecker(CheckerManager &Mgr) {
Mgr.registerChecker<RetainReleaseChecker>();
}

View File

@ -50,7 +50,7 @@ static inline Selector GetNullarySelector(const char* name, ASTContext &Ctx) {
// Engine construction and deletion.
//===----------------------------------------------------------------------===//
ExprEngine::ExprEngine(AnalysisManager &mgr, TransferFuncs *tf)
ExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled)
: AMgr(mgr),
Engine(*this),
G(Engine.getGraph()),
@ -63,10 +63,7 @@ ExprEngine::ExprEngine(AnalysisManager &mgr, TransferFuncs *tf)
EntryNode(NULL), currentStmt(NULL),
NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
RaiseSel(GetNullarySelector("raise", getContext())),
BR(mgr, *this), TF(tf) {
// FIXME: Eventually remove the TF object entirely.
TF->RegisterChecks(*this);
BR(mgr, *this), ObjCGCEnabled(gcEnabled) {
if (mgr.shouldEagerlyTrimExplodedGraph()) {
// Enable eager node reclaimation when constructing the ExplodedGraph.

View File

@ -262,8 +262,8 @@ static void FindBlocks(DeclContext *D, SmallVectorImpl<Decl*> &WL) {
FindBlocks(DC, WL);
}
static void ActionObjCMemChecker(AnalysisConsumer &C, AnalysisManager& mgr,
Decl *D);
static void RunPathSensitiveChecks(AnalysisConsumer &C, AnalysisManager &mgr,
Decl *D);
void AnalysisConsumer::HandleCode(Decl *D) {
@ -295,7 +295,7 @@ void AnalysisConsumer::HandleCode(Decl *D) {
if ((*WI)->hasBody()) {
checkerMgr->runCheckersOnASTBody(*WI, *Mgr, BR);
if (checkerMgr->hasPathSensitiveCheckers())
ActionObjCMemChecker(*this, *Mgr, *WI);
RunPathSensitiveChecks(*this, *Mgr, *WI);
}
}
@ -303,18 +303,14 @@ void AnalysisConsumer::HandleCode(Decl *D) {
// Path-sensitive checking.
//===----------------------------------------------------------------------===//
static void ActionExprEngine(AnalysisConsumer &C, AnalysisManager& mgr,
Decl *D,
TransferFuncs* tf) {
llvm::OwningPtr<TransferFuncs> TF(tf);
static void ActionExprEngine(AnalysisConsumer &C, AnalysisManager &mgr,
Decl *D, bool ObjCGCEnabled) {
// Construct the analysis engine. We first query for the LiveVariables
// information to see if the CFG is valid.
// FIXME: Inter-procedural analysis will need to handle invalid CFGs.
if (!mgr.getLiveVariables(D))
return;
ExprEngine Eng(mgr, TF.take());
ExprEngine Eng(mgr, ObjCGCEnabled);
// Set the graph auditor.
llvm::OwningPtr<ExplodedNode::Auditor> Auditor;
@ -338,35 +334,25 @@ static void ActionExprEngine(AnalysisConsumer &C, AnalysisManager& mgr,
Eng.getBugReporter().FlushReports();
}
static void ActionObjCMemCheckerAux(AnalysisConsumer &C, AnalysisManager& mgr,
Decl *D, bool GCEnabled) {
static void RunPathSensitiveChecks(AnalysisConsumer &C, AnalysisManager &mgr,
Decl *D) {
TransferFuncs* TF = MakeCFRefCountTF(mgr.getASTContext(),
GCEnabled,
mgr.getLangOptions());
ActionExprEngine(C, mgr, D, TF);
}
static void ActionObjCMemChecker(AnalysisConsumer &C, AnalysisManager& mgr,
Decl *D) {
switch (mgr.getLangOptions().getGCMode()) {
default:
assert (false && "Invalid GC mode.");
case LangOptions::NonGC:
ActionObjCMemCheckerAux(C, mgr, D, false);
break;
case LangOptions::GCOnly:
ActionObjCMemCheckerAux(C, mgr, D, true);
break;
case LangOptions::HybridGC:
ActionObjCMemCheckerAux(C, mgr, D, false);
ActionObjCMemCheckerAux(C, mgr, D, true);
break;
}
switch (mgr.getLangOptions().getGCMode()) {
default:
llvm_unreachable("Invalid GC mode.");
case LangOptions::NonGC:
ActionExprEngine(C, mgr, D, false);
break;
case LangOptions::GCOnly:
ActionExprEngine(C, mgr, D, true);
break;
case LangOptions::HybridGC:
ActionExprEngine(C, mgr, D, false);
ActionExprEngine(C, mgr, D, true);
break;
}
}
//===----------------------------------------------------------------------===//

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-constraints=basic -verify -fobjc-gc %s -Wno-implicit-function-declaration
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-constraints=range -verify -fobjc-gc %s -Wno-implicit-function-declaration
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -analyzer-constraints=basic -verify -fobjc-gc %s -Wno-implicit-function-declaration
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -analyzer-constraints=range -verify -fobjc-gc %s -Wno-implicit-function-declaration
//===----------------------------------------------------------------------===//
// The following code is reduced using delta-debugging from

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.coreFoundation.CFNumber -analyzer-store=region -analyzer-constraints=basic -verify -triple x86_64-apple-darwin9 %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.coreFoundation.CFNumber -analyzer-store=region -analyzer-constraints=range -verify -triple x86_64-apple-darwin9 %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.coreFoundation.CFNumber,osx.cocoa.RetainCount -analyzer-store=region -analyzer-constraints=basic -verify -triple x86_64-apple-darwin9 %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.coreFoundation.CFNumber,osx.cocoa.RetainCount -analyzer-store=region -analyzer-constraints=range -verify -triple x86_64-apple-darwin9 %s
typedef signed long CFIndex;
typedef const struct __CFAllocator * CFAllocatorRef;

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -verify %s -analyzer-constraints=basic -analyzer-store=region
// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -verify %s -analyzer-constraints=range -analyzer-store=region
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -verify %s -analyzer-constraints=basic -analyzer-store=region
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -verify %s -analyzer-constraints=range -analyzer-store=region
typedef struct objc_selector *SEL;
typedef signed char BOOL;

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-constraints=basic -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-constraints=range -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -analyzer-constraints=basic -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -analyzer-constraints=range -verify %s
typedef struct CGColorSpace *CGColorSpaceRef;
extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void);

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -analyzer-constraints=basic -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -analyzer-constraints=range -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-store=region -analyzer-constraints=basic -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-store=region -analyzer-constraints=range -verify %s
// BEGIN delta-debugging reduced header stuff

View File

@ -1,7 +1,7 @@
// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.AtomicCAS,experimental.core -analyzer-store=region -analyzer-constraints=basic -verify %s
// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.AtomicCAS,experimental.core -analyzer-store=region -analyzer-constraints=range -verify %s
// RUN: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.AtomicCAS,experimental.core -analyzer-store=region -analyzer-constraints=basic -verify %s
// RUN: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.AtomicCAS,experimental.core -analyzer-store=region -analyzer-constraints=range -verify %s
// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,osx.AtomicCAS,experimental.core -analyzer-store=region -analyzer-constraints=basic -verify %s
// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,osx.AtomicCAS,experimental.core -analyzer-store=region -analyzer-constraints=range -verify %s
// RUN: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,osx.AtomicCAS,experimental.core -analyzer-store=region -analyzer-constraints=basic -verify %s
// RUN: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,osx.AtomicCAS,experimental.core -analyzer-store=region -analyzer-constraints=range -verify %s
//===----------------------------------------------------------------------===//

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-checker=deadcode.DeadStores -analyzer-store=region -analyzer-constraints=basic -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-checker=deadcode.DeadStores -analyzer-store=region -analyzer-constraints=range -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core,deadcode.DeadStores -analyzer-store=region -analyzer-constraints=basic -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core,deadcode.DeadStores -analyzer-store=region -analyzer-constraints=range -verify %s
// These declarations were reduced using Delta-Debugging from Foundation.h
// on Mac OS X. The test cases are below.

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-constraints=range -analyzer-store=region -fobjc-gc -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-constraints=range -analyzer-store=region -fobjc-gc -verify %s
typedef const void * CFTypeRef;
typedef const struct __CFString * CFStringRef;

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -analyzer-constraints=basic -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -analyzer-constraints=range -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-store=region -analyzer-constraints=basic -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-store=region -analyzer-constraints=range -verify %s
typedef unsigned char Boolean;
typedef signed long CFIndex;

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.core -analyzer-checker=deadcode.DeadStores -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.core -analyzer-checker=deadcode.DeadStores,osx.cocoa.RetainCount -verify %s
typedef signed char BOOL;
typedef unsigned int NSUInteger;

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify %s
//===----------------------------------------------------------------------===//

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-checker=deadcode.IdempotentOperations -verify %s
// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-checker=deadcode.IdempotentOperations,osx.cocoa.RetainCount -verify %s
typedef signed char BOOL;
typedef unsigned long NSUInteger;

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core -analyzer-checker=deadcode -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks -fobjc-nonfragile-abi -fobjc-arc %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,deadcode -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks -fobjc-nonfragile-abi -fobjc-arc %s
typedef signed char BOOL;
typedef struct _NSZone NSZone;

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-output=plist -o - %s | FileCheck %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-output=plist -o - %s | FileCheck %s
void test_null_init(void) {
int *p = 0;

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -pedantic -analyzer-store=region -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -pedantic -analyzer-store=region -verify %s
// BEGIN delta-debugging reduced header stuff

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify %s
typedef signed char BOOL;
typedef unsigned int NSUInteger;

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-constraints=basic -analyzer-store=region -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-constraints=basic -analyzer-store=region -verify %s
//
// This test case mainly checks that the retain/release checker doesn't crash
// on this file.

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-store=region -verify %s
typedef const struct __CFString * CFStringRef;
typedef const struct __CFAllocator * CFAllocatorRef;

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.NSAutoreleasePool -analyzer-store=region -fobjc-gc-only -fblocks -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.NSAutoreleasePool -analyzer-store=region -fobjc-gc-only -fblocks -verify %s
//===----------------------------------------------------------------------===//
// Header stuff.

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=region -analyzer-output=text -fobjc-gc-only -verify %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=text -fobjc-gc-only -verify %s
/***
This file is for testing the path-sensitive notes for retain/release errors.

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=region -analyzer-output=text -verify %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=text -verify %s
/***
This file is for testing the path-sensitive notes for retain/release errors.

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-max-loop 6 -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -analyzer-max-loop 6 -verify %s
//===----------------------------------------------------------------------===//
// The following code is reduced using delta-debugging from

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=region -fblocks -verify %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=region -fblocks -verify -x objective-c++ %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify -x objective-c++ %s
#if __has_feature(attribute_ns_returns_retained)
#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=region -fblocks -verify %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify %s
#if __has_feature(attribute_ns_returns_retained)
#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))