diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/AnalysisManager.cpp | 8 | ||||
-rw-r--r-- | lib/Analysis/BugReporter.cpp | 16 | ||||
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 10 | ||||
-rw-r--r-- | lib/Analysis/CheckDeadStores.cpp | 9 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 26 | ||||
-rw-r--r-- | lib/Frontend/AnalysisConsumer.cpp | 101 |
6 files changed, 86 insertions, 84 deletions
diff --git a/lib/Analysis/AnalysisManager.cpp b/lib/Analysis/AnalysisManager.cpp index 623db17b92..1aa459a28d 100644 --- a/lib/Analysis/AnalysisManager.cpp +++ b/lib/Analysis/AnalysisManager.cpp @@ -16,7 +16,7 @@ using namespace clang; -void AnalysisManager::DisplayFunction() { +void AnalysisManager::DisplayFunction(Decl *D) { if (DisplayedFunction) return; @@ -24,12 +24,12 @@ void AnalysisManager::DisplayFunction() { DisplayedFunction = true; // FIXME: Is getCodeDecl() always a named decl? - if (isa<FunctionDecl>(getCodeDecl()) || - isa<ObjCMethodDecl>(getCodeDecl())) { - const NamedDecl *ND = cast<NamedDecl>(getCodeDecl()); + if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) { + const NamedDecl *ND = cast<NamedDecl>(D); SourceManager &SM = getASTContext().getSourceManager(); llvm::errs() << "ANALYZE: " << SM.getPresumedLoc(ND->getLocation()).getFilename() << ' ' << ND->getNameAsString() << '\n'; } } + diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp index 23ca53d6e9..c15161c708 100644 --- a/lib/Analysis/BugReporter.cpp +++ b/lib/Analysis/BugReporter.cpp @@ -36,14 +36,6 @@ BugReporterContext::~BugReporterContext() { if ((*I)->isOwnedByReporterContext()) delete *I; } -const Decl& BugReporterContext::getCodeDecl() { - return *BR.getEngine().getAnalysisManager().getCodeDecl(); -} - -const CFG& BugReporterContext::getCFG() { - return *BR.getEngine().getAnalysisManager().getCFG(); -} - //===----------------------------------------------------------------------===// // Helper routines for walking the ExplodedGraph and fetching statements. //===----------------------------------------------------------------------===// @@ -158,11 +150,9 @@ public: PathDiagnosticLocation ExecutionContinues(llvm::raw_string_ostream& os, const ExplodedNode* N); - ParentMap& getParentMap() { - if (PM.get() == 0) - PM.reset(new ParentMap(getCodeDecl().getBody())); - return *PM.get(); - } + Decl const &getCodeDecl() { return R->getEndNode()->getCodeDecl(); } + + ParentMap& getParentMap() { return R->getEndNode()->getParentMap(); } const Stmt *getParent(const Stmt *S) { return getParentMap().getParent(S); diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index e511f76195..8427679316 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -2641,7 +2641,7 @@ CFRefLeakReport::getEndPath(BugReporterContext& BRC, } if (!L.isValid()) { - const Decl &D = BRC.getCodeDecl(); + const Decl &D = EndN->getCodeDecl(); L = PathDiagnosticLocation(D.getBodyRBrace(), SMgr); } @@ -2660,7 +2660,7 @@ CFRefLeakReport::getEndPath(BugReporterContext& BRC, // FIXME: Per comments in rdar://6320065, "create" only applies to CF // ojbects. Only "copy", "alloc", "retain" and "new" transfer ownership // to the caller for NS objects. - ObjCMethodDecl& MD = cast<ObjCMethodDecl>(BRC.getCodeDecl()); + ObjCMethodDecl& MD = cast<ObjCMethodDecl>(EndN->getCodeDecl()); os << " is returned from a method whose name ('" << MD.getSelector().getAsString() << "') does not contain 'copy' or otherwise starts with" @@ -2668,7 +2668,7 @@ CFRefLeakReport::getEndPath(BugReporterContext& BRC, " in the Memory Management Guide for Cocoa (object leaked)"; } else if (RV->getKind() == RefVal::ErrorGCLeakReturned) { - ObjCMethodDecl& MD = cast<ObjCMethodDecl>(BRC.getCodeDecl()); + ObjCMethodDecl& MD = cast<ObjCMethodDecl>(EndN->getCodeDecl()); os << " and returned from method '" << MD.getSelector().getAsString() << "' is potentially leaked when using garbage collection. Callers " "of this method do not expect a returned object with a +1 retain " @@ -3186,7 +3186,7 @@ void CFRefCount::EvalReturn(ExplodedNodeSet& Dst, // Any leaks or other errors? if (X.isReturnedOwned() && X.getCount() == 0) { - const Decl *CD = Eng.getAnalysisManager().getCodeDecl(); + Decl const *CD = &Pred->getCodeDecl(); if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(CD)) { const RetainSummary &Summ = *Summaries.getMethodSummary(MD); RetEffect RE = Summ.getRetEffect(); @@ -3229,7 +3229,7 @@ void CFRefCount::EvalReturn(ExplodedNodeSet& Dst, } } else if (X.isReturnedNotOwned()) { - const Decl *CD = Eng.getAnalysisManager().getCodeDecl(); + Decl const *CD = &Pred->getCodeDecl(); if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(CD)) { const RetainSummary &Summ = *Summaries.getMethodSummary(MD); if (Summ.getRetEffect().isOwned()) { diff --git a/lib/Analysis/CheckDeadStores.cpp b/lib/Analysis/CheckDeadStores.cpp index 716affb846..d5cb7ca7fd 100644 --- a/lib/Analysis/CheckDeadStores.cpp +++ b/lib/Analysis/CheckDeadStores.cpp @@ -251,9 +251,10 @@ public: } // end anonymous namespace -void clang::CheckDeadStores(LiveVariables& L, BugReporter& BR) { - FindEscaped FS(BR.getCFG()); +void clang::CheckDeadStores(CFG &cfg, LiveVariables &L, ParentMap &pmap, + BugReporter& BR) { + FindEscaped FS(&cfg); FS.getCFG().VisitBlockStmts(FS); - DeadStoreObs A(BR.getContext(), BR, BR.getParentMap(), FS.Escaped); - L.runOnAllBlocks(*BR.getCFG(), &A); + DeadStoreObs A(BR.getContext(), BR, pmap, FS.Escaped); + L.runOnAllBlocks(cfg, &A); } diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index ff9554c836..986af1023b 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -262,7 +262,8 @@ void GRExprEngine::ProcessStmt(Stmt* S, GRStmtNodeBuilder& builder) { Builder->setAuditor(BatchAuditor.get()); // Create the cleaned state. - SymbolReaper SymReaper(*AMgr.getLiveVariables(), SymMgr); + SymbolReaper SymReaper(Builder->getBasePredecessor()->getLiveVariables(), + SymMgr); CleanedState = AMgr.shouldPurgeDead() ? StateMgr.RemoveDeadBindings(EntryNode->getState(), CurrentStmt, SymReaper) : EntryNode->getState(); @@ -1670,7 +1671,8 @@ void GRExprEngine::VisitCallRec(CallExpr* CE, ExplodedNode* Pred, static std::pair<const void*,const void*> EagerlyAssumeTag = std::pair<const void*,const void*>(&EagerlyAssumeTag,0); -void GRExprEngine::EvalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, Expr *Ex) { +void GRExprEngine::EvalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, + Expr *Ex) { for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) { ExplodedNode *Pred = *I; @@ -1713,9 +1715,8 @@ void GRExprEngine::EvalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, // Transfer function: Objective-C ivar references. //===----------------------------------------------------------------------===// -void GRExprEngine::VisitObjCIvarRefExpr(ObjCIvarRefExpr* Ex, - ExplodedNode* Pred, ExplodedNodeSet& Dst, - bool asLValue) { +void GRExprEngine::VisitObjCIvarRefExpr(ObjCIvarRefExpr* Ex, ExplodedNode* Pred, + ExplodedNodeSet& Dst, bool asLValue) { Expr* Base = cast<Expr>(Ex->getBase()); ExplodedNodeSet Tmp; @@ -1738,7 +1739,7 @@ void GRExprEngine::VisitObjCIvarRefExpr(ObjCIvarRefExpr* Ex, //===----------------------------------------------------------------------===// void GRExprEngine::VisitObjCForCollectionStmt(ObjCForCollectionStmt* S, - ExplodedNode* Pred, ExplodedNodeSet& Dst) { + ExplodedNode* Pred, ExplodedNodeSet& Dst) { // ObjCForCollectionStmts are processed in two places. This method // handles the case where an ObjCForCollectionStmt* occurs as one of the @@ -1786,7 +1787,7 @@ void GRExprEngine::VisitObjCForCollectionStmt(ObjCForCollectionStmt* S, } void GRExprEngine::VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S, - ExplodedNode* Pred, ExplodedNodeSet& Dst, + ExplodedNode* Pred, ExplodedNodeSet& Dst, SVal ElementV) { @@ -1845,7 +1846,7 @@ void GRExprEngine::VisitObjCMessageExpr(ObjCMessageExpr* ME, ExplodedNode* Pred, void GRExprEngine::VisitObjCMessageExprArgHelper(ObjCMessageExpr* ME, ObjCMessageExpr::arg_iterator AI, ObjCMessageExpr::arg_iterator AE, - ExplodedNode* Pred, ExplodedNodeSet& Dst) { + ExplodedNode* Pred, ExplodedNodeSet& Dst) { if (AI == AE) { // Process the receiver. @@ -1854,7 +1855,8 @@ void GRExprEngine::VisitObjCMessageExprArgHelper(ObjCMessageExpr* ME, ExplodedNodeSet Tmp; Visit(Receiver, Pred, Tmp); - for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI) + for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; + ++NI) VisitObjCMessageExprDispatchHelper(ME, *NI, Dst); return; @@ -1869,7 +1871,7 @@ void GRExprEngine::VisitObjCMessageExprArgHelper(ObjCMessageExpr* ME, ++AI; - for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI != NE; ++NI) + for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end();NI != NE;++NI) VisitObjCMessageExprArgHelper(ME, AI, AE, *NI, Dst); } @@ -1910,7 +1912,7 @@ void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME, // Check if the receiver was nil and the return value a struct. if (RetTy->isRecordType()) { - if (BR.getParentMap().isConsumedExpr(ME)) { + if (Pred->getParentMap().isConsumedExpr(ME)) { // The [0 ...] expressions will return garbage. Flag either an // explicit or implicit error. Because of the structure of this // function we currently do not bifurfacte the state graph at @@ -1929,7 +1931,7 @@ void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME, else { ASTContext& Ctx = getContext(); if (RetTy != Ctx.VoidTy) { - if (BR.getParentMap().isConsumedExpr(ME)) { + if (Pred->getParentMap().isConsumedExpr(ME)) { // sizeof(void *) const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy); // sizeof(return type) diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp index 2d07d89e04..67328da661 100644 --- a/lib/Frontend/AnalysisConsumer.cpp +++ b/lib/Frontend/AnalysisConsumer.cpp @@ -45,7 +45,7 @@ static ExplodedNode::Auditor* CreateUbiViz(); //===----------------------------------------------------------------------===// namespace { - typedef void (*CodeAction)(AnalysisManager& Mgr); + typedef void (*CodeAction)(AnalysisManager& Mgr, Decl *D); } // end anonymous namespace //===----------------------------------------------------------------------===// @@ -223,10 +223,23 @@ void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) { } void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) { - if (!TranslationUnitActions.empty()) { - for (Actions::iterator I = TranslationUnitActions.begin(), + // Find the entry function definition. + FunctionDecl *FD = 0; + TranslationUnitDecl *TU = Ctx->getTranslationUnitDecl(); + for (DeclContext::decl_iterator I = TU->decls_begin(), E = TU->decls_end(); + I != E; ++I) { + if (FunctionDecl *fd = dyn_cast<FunctionDecl>(*I)) + if (fd->isThisDeclarationADefinition() && + fd->getNameAsString() == Opts.AnalyzeSpecificFunction) { + FD = fd; + break; + } + } + + if(!TranslationUnitActions.empty()) { + for (Actions::iterator I = TranslationUnitActions.begin(), E = TranslationUnitActions.end(); I != E; ++I) - (*I)(*Mgr); + (*I)(*Mgr, FD); } if (!ObjCImplementationActions.empty()) { @@ -245,7 +258,7 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) { Mgr.reset(NULL); } -void AnalysisConsumer::HandleCode(Decl* D, Stmt* Body, Actions& actions) { +void AnalysisConsumer::HandleCode(Decl *D, Stmt* Body, Actions& actions) { // Don't run the actions if an error has occured with parsing the file. if (Diags.hasErrorOccurred()) @@ -257,41 +270,40 @@ void AnalysisConsumer::HandleCode(Decl* D, Stmt* Body, Actions& actions) { !Ctx->getSourceManager().isFromMainFile(D->getLocation())) return; - Mgr->setEntryContext(D); - // Dispatch on the actions. for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I) - (*I)(*Mgr); + (*I)(*Mgr, D); } //===----------------------------------------------------------------------===// // Analyses //===----------------------------------------------------------------------===// -static void ActionWarnDeadStores(AnalysisManager& mgr) { - if (LiveVariables* L = mgr.getLiveVariables()) { +static void ActionWarnDeadStores(AnalysisManager& mgr, Decl *D) { + if (LiveVariables *L = mgr.getLiveVariables(D)) { BugReporter BR(mgr); - CheckDeadStores(*L, BR); + CheckDeadStores(*mgr.getCFG(D), *L, mgr.getParentMap(D), BR); } } -static void ActionWarnUninitVals(AnalysisManager& mgr) { - if (CFG* c = mgr.getCFG()) +static void ActionWarnUninitVals(AnalysisManager& mgr, Decl *D) { + if (CFG* c = mgr.getCFG(D)) CheckUninitializedValues(*c, mgr.getASTContext(), mgr.getDiagnostic()); } -static void ActionGRExprEngine(AnalysisManager& mgr, GRTransferFuncs* tf, +static void ActionGRExprEngine(AnalysisManager& mgr, Decl *D, + GRTransferFuncs* tf, bool StandardWarnings = true) { llvm::OwningPtr<GRTransferFuncs> TF(tf); // Display progress. - mgr.DisplayFunction(); + mgr.DisplayFunction(D); // Construct the analysis engine. - LiveVariables* L = mgr.getLiveVariables(); + LiveVariables* L = mgr.getLiveVariables(D); if (!L) return; GRExprEngine Eng(mgr); @@ -300,7 +312,7 @@ static void ActionGRExprEngine(AnalysisManager& mgr, GRTransferFuncs* tf, if (StandardWarnings) { Eng.RegisterInternalChecks(); - RegisterAppleChecks(Eng, *mgr.getCodeDecl()); + RegisterAppleChecks(Eng, *D); } // Set the graph auditor. @@ -311,7 +323,7 @@ static void ActionGRExprEngine(AnalysisManager& mgr, GRTransferFuncs* tf, } // Execute the worklist algorithm. - Eng.ExecuteWorkList(mgr.getEntryStackFrame()); + Eng.ExecuteWorkList(mgr.getStackFrame(D)); // Release the auditor (if any) so that it doesn't monitor the graph // created BugReporter. @@ -325,82 +337,79 @@ static void ActionGRExprEngine(AnalysisManager& mgr, GRTransferFuncs* tf, Eng.getBugReporter().FlushReports(); } -static void ActionCheckerCFRefAux(AnalysisManager& mgr, bool GCEnabled, - bool StandardWarnings) { +static void ActionCheckerCFRefAux(AnalysisManager& mgr, Decl *D, + bool GCEnabled, bool StandardWarnings) { GRTransferFuncs* TF = MakeCFRefCountTF(mgr.getASTContext(), GCEnabled, mgr.getLangOptions()); - ActionGRExprEngine(mgr, TF, StandardWarnings); + ActionGRExprEngine(mgr, D, TF, StandardWarnings); } -static void ActionCheckerCFRef(AnalysisManager& mgr) { +static void ActionCheckerCFRef(AnalysisManager& mgr, Decl *D) { switch (mgr.getLangOptions().getGCMode()) { default: assert (false && "Invalid GC mode."); case LangOptions::NonGC: - ActionCheckerCFRefAux(mgr, false, true); + ActionCheckerCFRefAux(mgr, D, false, true); break; case LangOptions::GCOnly: - ActionCheckerCFRefAux(mgr, true, true); + ActionCheckerCFRefAux(mgr, D, true, true); break; case LangOptions::HybridGC: - ActionCheckerCFRefAux(mgr, false, true); - ActionCheckerCFRefAux(mgr, true, false); + ActionCheckerCFRefAux(mgr, D, false, true); + ActionCheckerCFRefAux(mgr, D, true, false); break; } } -static void ActionDisplayLiveVariables(AnalysisManager& mgr) { - if (LiveVariables* L = mgr.getLiveVariables()) { - mgr.DisplayFunction(); +static void ActionDisplayLiveVariables(AnalysisManager& mgr, Decl *D) { + if (LiveVariables* L = mgr.getLiveVariables(D)) { + mgr.DisplayFunction(D); L->dumpBlockLiveness(mgr.getSourceManager()); } } -static void ActionCFGDump(AnalysisManager& mgr) { - if (CFG* c = mgr.getCFG()) { - mgr.DisplayFunction(); +static void ActionCFGDump(AnalysisManager& mgr, Decl *D) { + if (CFG* c = mgr.getCFG(D)) { + mgr.DisplayFunction(D); c->dump(mgr.getLangOptions()); } } -static void ActionCFGView(AnalysisManager& mgr) { - if (CFG* c = mgr.getCFG()) { - mgr.DisplayFunction(); +static void ActionCFGView(AnalysisManager& mgr, Decl *D) { + if (CFG* c = mgr.getCFG(D)) { + mgr.DisplayFunction(D); c->viewCFG(mgr.getLangOptions()); } } -static void ActionSecuritySyntacticChecks(AnalysisManager &mgr) { +static void ActionSecuritySyntacticChecks(AnalysisManager &mgr, Decl *D) { BugReporter BR(mgr); - CheckSecuritySyntaxOnly(mgr.getCodeDecl(), BR); + CheckSecuritySyntaxOnly(D, BR); } -static void ActionWarnObjCDealloc(AnalysisManager& mgr) { +static void ActionWarnObjCDealloc(AnalysisManager& mgr, Decl *D) { if (mgr.getLangOptions().getGCMode() == LangOptions::GCOnly) return; BugReporter BR(mgr); - - CheckObjCDealloc(cast<ObjCImplementationDecl>(mgr.getCodeDecl()), - mgr.getLangOptions(), BR); + CheckObjCDealloc(cast<ObjCImplementationDecl>(D), mgr.getLangOptions(), BR); } -static void ActionWarnObjCUnusedIvars(AnalysisManager& mgr) { +static void ActionWarnObjCUnusedIvars(AnalysisManager& mgr, Decl *D) { BugReporter BR(mgr); - CheckObjCUnusedIvar(cast<ObjCImplementationDecl>(mgr.getCodeDecl()), BR); + CheckObjCUnusedIvar(cast<ObjCImplementationDecl>(D), BR); } -static void ActionWarnObjCMethSigs(AnalysisManager& mgr) { +static void ActionWarnObjCMethSigs(AnalysisManager& mgr, Decl *D) { BugReporter BR(mgr); - CheckObjCInstMethSignature(cast<ObjCImplementationDecl>(mgr.getCodeDecl()), - BR); + CheckObjCInstMethSignature(cast<ObjCImplementationDecl>(D), BR); } //===----------------------------------------------------------------------===// |