AnalysisConsumer.cpp revision 43dee220252ef0b42c5f8a3bb1eca97f84f2565f
1f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===--- AnalysisConsumer.cpp - ASTConsumer for running Analyses ----------===// 2f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// 3f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// The LLVM Compiler Infrastructure 4f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// 5f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// This file is distributed under the University of Illinois Open Source 6f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// License. See LICENSE.TXT for details. 7f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// 8f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===// 9f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// 10f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// "Meta" ASTConsumer for running different source analyses. 11f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// 12f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===// 13f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 14e6348c336fecc8da9288ea367375a1b1cd2358d2Argyrios Kyrtzidis#include "AnalysisConsumer.h" 15f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "clang/AST/ASTConsumer.h" 16f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "clang/AST/Decl.h" 17802be99a6817aba6edb166b93c133da4358aa783Zhongxing Xu#include "clang/AST/DeclCXX.h" 18f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "clang/AST/DeclObjC.h" 19efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/AST/ParentMap.h" 20efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/Analysis/Analyses/LiveVariables.h" 211309f9a3b225ea846e5822691c39a77423125505Ted Kremenek#include "clang/Analysis/Analyses/UninitializedValues.h" 22efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/Analysis/CFG.h" 2343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerManager.h" 2421142581d55918beed544a757e4af3bb865b1812Ted Kremenek#include "clang/StaticAnalyzer/Checkers/LocalCheckers.h" 259b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h" 269b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 279b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" 289b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 299b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/TransferFuncs.h" 309b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathDiagnosticClients.h" 31a7af5ea88a6c5bdf87497cca6c20831e8c546751Argyrios Kyrtzidis 32a7af5ea88a6c5bdf87497cca6c20831e8c546751Argyrios Kyrtzidis// FIXME: Restructure checker registration. 33e817771c57d0eacbe069a314ba619c43d0ac70abArgyrios Kyrtzidis#include "../Checkers/ExperimentalChecks.h" 34e817771c57d0eacbe069a314ba619c43d0ac70abArgyrios Kyrtzidis#include "../Checkers/InternalChecks.h" 35a7af5ea88a6c5bdf87497cca6c20831e8c546751Argyrios Kyrtzidis 36efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/Basic/FileManager.h" 37efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/Basic/SourceManager.h" 389b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#include "clang/Frontend/AnalyzerOptions.h" 39efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/Lex/Preprocessor.h" 40f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek#include "llvm/Support/raw_ostream.h" 4103013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Path.h" 4203013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Program.h" 436cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer#include "llvm/ADT/OwningPtr.h" 44db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek 45f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenekusing namespace clang; 469ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento; 47f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 48c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xustatic ExplodedNode::Auditor* CreateUbiViz(); 49ff944a8c481d6c0f1ad2633e4be9bf8b1dd2a09fZhongxing Xu 50be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek//===----------------------------------------------------------------------===// 51f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek// Special PathDiagnosticClients. 52f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek//===----------------------------------------------------------------------===// 53f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek 54f75560670bcdd59b051149bdece3eac14e313853Ted Kremenekstatic PathDiagnosticClient* 55f928dca56542cf8f981a684f090d2c79bdcb2a10Argyrios KyrtzidiscreatePlistHTMLDiagnosticClient(const std::string& prefix, 56efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar const Preprocessor &PP) { 57d5b08bee799d4f77f1a25fa5977ca77b983ab031Michael J. Spencer PathDiagnosticClient *PD = 58d5b08bee799d4f77f1a25fa5977ca77b983ab031Michael J. Spencer createHTMLDiagnosticClient(llvm::sys::path::parent_path(prefix), PP); 59f928dca56542cf8f981a684f090d2c79bdcb2a10Argyrios Kyrtzidis return createPlistDiagnosticClient(prefix, PP, PD); 60f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek} 61f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek 62f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek//===----------------------------------------------------------------------===// 63f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// AnalysisConsumer declaration. 64f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===// 65f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 66f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremeneknamespace { 67f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 68ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xuclass AnalysisConsumer : public ASTConsumer { 69ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xupublic: 706490ae5003226cae28f980648948bea8b21a8638Douglas Gregor typedef void (*CodeAction)(AnalysisConsumer &C, AnalysisManager &M, Decl *D); 71f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek typedef void (*TUAction)(AnalysisConsumer &C, AnalysisManager &M, 72f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek TranslationUnitDecl &TU); 73f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 74ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xuprivate: 751d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek typedef std::vector<CodeAction> Actions; 76f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek typedef std::vector<TUAction> TUActions; 77f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 781d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek Actions FunctionActions; 791d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek Actions ObjCMethodActions; 801d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek Actions ObjCImplementationActions; 81ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu Actions CXXMethodActions; 82ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu TUActions TranslationUnitActions; // Remove this. 831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 841d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekpublic: 851d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek ASTContext* Ctx; 861d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek const Preprocessor &PP; 871d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek const std::string OutDir; 881d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek AnalyzerOptions Opts; 89d07a0d0279c09d1017f8450fce575a94dc9703c0Zhongxing Xu 901d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek // PD is owned by AnalysisManager. 911d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek PathDiagnosticClient *PD; 92d07a0d0279c09d1017f8450fce575a94dc9703c0Zhongxing Xu 931d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek StoreManagerCreator CreateStoreMgr; 941d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek ConstraintManagerCreator CreateConstraintMgr; 95f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 9643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis llvm::OwningPtr<CheckerManager> checkerMgr; 971d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek llvm::OwningPtr<AnalysisManager> Mgr; 98c471e7b44e63ff1b46b480e723c4130aeaef5a8aZhongxing Xu 991d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek AnalysisConsumer(const Preprocessor& pp, 1001d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek const std::string& outdir, 1011d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek const AnalyzerOptions& opts) 1021d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek : Ctx(0), PP(pp), OutDir(outdir), 103c4a1437c15da43eb8d2601cdce13161ef41a4389Ted Kremenek Opts(opts), PD(0) { 1041d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek DigestAnalyzerOptions(); 1051d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek } 106fda7832b000ff8927386f093b52c067641679469Zhongxing Xu 1071d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek void DigestAnalyzerOptions() { 1081d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek // Create the PathDiagnosticClient. 1091d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek if (!OutDir.empty()) { 1101d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek switch (Opts.AnalysisDiagOpt) { 1111d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek default: 112fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE) \ 1131d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek case PD_##NAME: PD = CREATEFN(OutDir, PP); break; 114fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#include "clang/Frontend/Analyses.def" 115fda7832b000ff8927386f093b52c067641679469Zhongxing Xu } 116a599ae8826b01c0160a519b0fc5a4871f599bf04Argyrios Kyrtzidis } else if (Opts.AnalysisDiagOpt == PD_TEXT) { 117a599ae8826b01c0160a519b0fc5a4871f599bf04Argyrios Kyrtzidis // Create the text client even without a specified output file since 118a599ae8826b01c0160a519b0fc5a4871f599bf04Argyrios Kyrtzidis // it just uses diagnostic notes. 119a599ae8826b01c0160a519b0fc5a4871f599bf04Argyrios Kyrtzidis PD = createTextPathDiagnosticClient("", PP); 1201d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek } 121fda7832b000ff8927386f093b52c067641679469Zhongxing Xu 1221d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek // Create the analyzer component creators. 1235f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis switch (Opts.AnalysisStoreOpt) { 1245f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis default: 1255f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis assert(0 && "Unknown store manager."); 126fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATEFN) \ 1275f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis case NAME##Model: CreateStoreMgr = CREATEFN; break; 128fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#include "clang/Frontend/Analyses.def" 1291d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek } 1301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1315f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis switch (Opts.AnalysisConstraintsOpt) { 1325f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis default: 1335f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis assert(0 && "Unknown store manager."); 134fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATEFN) \ 1355f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis case NAME##Model: CreateConstraintMgr = CREATEFN; break; 136fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#include "clang/Frontend/Analyses.def" 137fda7832b000ff8927386f093b52c067641679469Zhongxing Xu } 1381d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek } 139f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 1401d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek void DisplayFunction(const Decl *D) { 141c4a1437c15da43eb8d2601cdce13161ef41a4389Ted Kremenek if (!Opts.AnalyzerDisplayProgress) 1421d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek return; 143f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 144fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek SourceManager &SM = Mgr->getASTContext().getSourceManager(); 145fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek PresumedLoc Loc = SM.getPresumedLoc(D->getLocation()); 146cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor if (Loc.isValid()) { 147cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor llvm::errs() << "ANALYZE: " << Loc.getFilename(); 148fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek 149cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) { 150cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor const NamedDecl *ND = cast<NamedDecl>(D); 151cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor llvm::errs() << ' ' << ND << '\n'; 152cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor } 153cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor else if (isa<BlockDecl>(D)) { 154cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor llvm::errs() << ' ' << "block(line:" << Loc.getLine() << ",col:" 155cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor << Loc.getColumn() << '\n'; 156cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor } 157cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 158cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor Selector S = MD->getSelector(); 159cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor llvm::errs() << ' ' << S.getAsString(); 160cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor } 16135fa76d0bb6fb8c86159a7506efd094a4fe376d2Ted Kremenek } 1621d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek } 1631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1641d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek void addCodeAction(CodeAction action) { 1651d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek FunctionActions.push_back(action); 1661d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek ObjCMethodActions.push_back(action); 167ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu CXXMethodActions.push_back(action); 1681d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek } 1691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 170f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek void addTranslationUnitAction(TUAction action) { 1711d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek TranslationUnitActions.push_back(action); 1721d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek } 1731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 174ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu void addObjCImplementationAction(CodeAction action) { 175ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu ObjCImplementationActions.push_back(action); 176ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu } 177ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu 1781d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek virtual void Initialize(ASTContext &Context) { 1791d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek Ctx = &Context; 18043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis checkerMgr.reset(registerCheckers(Opts, PP.getDiagnostics())); 1811d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek Mgr.reset(new AnalysisManager(*Ctx, PP.getDiagnostics(), 1821d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek PP.getLangOptions(), PD, 1831d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek CreateStoreMgr, CreateConstraintMgr, 18443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis checkerMgr.get(), 185c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu /* Indexer */ 0, 1866362b893731ccf4480a96527db9e55e04b801503Zhongxing Xu Opts.MaxNodes, Opts.MaxLoop, 1871d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek Opts.VisualizeEGDot, Opts.VisualizeEGUbi, 1881d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek Opts.PurgeDead, Opts.EagerlyAssume, 1899b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek Opts.TrimGraph, Opts.InlineCall, 1909121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski Opts.UnoptimizedCFG, Opts.CFGAddImplicitDtors, 191d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek Opts.CFGAddInitializers, 192d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek Opts.EagerlyTrimEGraph)); 1931d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek } 1941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1951d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek virtual void HandleTranslationUnit(ASTContext &C); 19614cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek void HandleDeclContext(ASTContext &C, DeclContext *dc); 19714cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek 19806a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidis void HandleCode(Decl *D, Actions& actions); 1991d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek}; 200f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek} // end anonymous namespace 201f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 202f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===// 203f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// AnalysisConsumer implementation. 204f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===// 205f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 20614cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenekvoid AnalysisConsumer::HandleDeclContext(ASTContext &C, DeclContext *dc) { 20714cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek for (DeclContext::decl_iterator I = dc->decls_begin(), E = dc->decls_end(); 208ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu I != E; ++I) { 209ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu Decl *D = *I; 21014cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek 211ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu switch (D->getKind()) { 21214cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek case Decl::Namespace: { 21314cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek HandleDeclContext(C, cast<NamespaceDecl>(D)); 21414cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek break; 215ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu } 21614cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek case Decl::CXXConstructor: 21714cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek case Decl::CXXDestructor: 21814cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek case Decl::CXXConversion: 21914cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek case Decl::CXXMethod: 22014cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek case Decl::Function: { 22114cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek FunctionDecl* FD = cast<FunctionDecl>(D); 22214cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek // We skip function template definitions, as their semantics is 22314cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek // only determined when they are instantiated. 22414cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek if (FD->isThisDeclarationADefinition() && 22514cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek !FD->isDependentContext()) { 226ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu if (!Opts.AnalyzeSpecificFunction.empty() && 22714cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek FD->getDeclName().getAsString() != Opts.AnalyzeSpecificFunction) 228ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu break; 22914cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek DisplayFunction(FD); 23014cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek HandleCode(FD, FunctionActions); 231ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu } 23214cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek break; 233ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu } 23414cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek 23514cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek case Decl::ObjCImplementation: { 23614cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek ObjCImplementationDecl* ID = cast<ObjCImplementationDecl>(*I); 23714cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek HandleCode(ID, ObjCImplementationActions); 23814cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek 23914cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek for (ObjCImplementationDecl::method_iterator MI = ID->meth_begin(), 24014cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek ME = ID->meth_end(); MI != ME; ++MI) { 24114cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek if ((*MI)->isThisDeclarationADefinition()) { 24214cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek if (!Opts.AnalyzeSpecificFunction.empty() && 24314cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek Opts.AnalyzeSpecificFunction != (*MI)->getSelector().getAsString()) 24414cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek break; 24514cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek DisplayFunction(*MI); 24614cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek HandleCode(*MI, ObjCMethodActions); 24714cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek } 24814cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek } 24914cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek break; 25014cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek } 25114cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek 25214cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek default: 25314cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek break; 254ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu } 25514cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek } 25614cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek} 257f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 25814cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenekvoid AnalysisConsumer::HandleTranslationUnit(ASTContext &C) { 25914cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek TranslationUnitDecl *TU = C.getTranslationUnitDecl(); 26014cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek HandleDeclContext(C, TU); 261b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu 262f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek for (TUActions::iterator I = TranslationUnitActions.begin(), 263f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek E = TranslationUnitActions.end(); I != E; ++I) { 264f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek (*I)(*this, *Mgr, *TU); 265daac634c9744257d43ce892b973019b16468caf2Ted Kremenek } 266daac634c9744257d43ce892b973019b16468caf2Ted Kremenek 267690a7f431d6863a101711e67636d51ddd13f35c5Ted Kremenek // Explicitly destroy the PathDiagnosticClient. This will flush its output. 268690a7f431d6863a101711e67636d51ddd13f35c5Ted Kremenek // FIXME: This should be replaced with something that doesn't rely on 269da17fd50ad485fd2a1fc5c2f055caacf532992daZhongxing Xu // side-effects in PathDiagnosticClient's destructor. This is required when 270da17fd50ad485fd2a1fc5c2f055caacf532992daZhongxing Xu // used with option -disable-free. 271d07a0d0279c09d1017f8450fce575a94dc9703c0Zhongxing Xu Mgr.reset(NULL); 272db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek} 273db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek 274fc576514d06c46a7cac49500169411d82f38d04bTed Kremenekstatic void FindBlocks(DeclContext *D, llvm::SmallVectorImpl<Decl*> &WL) { 275fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) 276fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek WL.push_back(BD); 277f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 278fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end(); 279fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek I!=E; ++I) 280fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek if (DeclContext *DC = dyn_cast<DeclContext>(*I)) 281fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek FindBlocks(DC, WL); 282fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek} 283fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek 28406a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidisvoid AnalysisConsumer::HandleCode(Decl *D, Actions& actions) { 2851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 286f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek // Don't run the actions if an error has occured with parsing the file. 28799e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek Diagnostic &Diags = PP.getDiagnostics(); 28899e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred()) 289f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek return; 29081922f01352aceeb923c0c3cc8c96b6527322384Ted Kremenek 291f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek // Don't run the actions on declarations in header files unless 292f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek // otherwise specified. 293fcd783d583d270b7ec1ec3e0fcf83cd93d30e381Ted Kremenek SourceManager &SM = Ctx->getSourceManager(); 294fcd783d583d270b7ec1ec3e0fcf83cd93d30e381Ted Kremenek SourceLocation SL = SM.getInstantiationLoc(D->getLocation()); 295fcd783d583d270b7ec1ec3e0fcf83cd93d30e381Ted Kremenek if (!Opts.AnalyzeAll && !SM.isFromMainFile(SL)) 2961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return; 297f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 29858f5ec7d56b1ebf5f90ee11226ebe7663f2821eaTed Kremenek // Clear the AnalysisManager of old AnalysisContexts. 29958f5ec7d56b1ebf5f90ee11226ebe7663f2821eaTed Kremenek Mgr->ClearContexts(); 300f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 3011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Dispatch on the actions. 302fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek llvm::SmallVector<Decl*, 10> WL; 303fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek WL.push_back(D); 304f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 30506a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidis if (D->hasBody() && Opts.AnalyzeNestedBlocks) 306fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek FindBlocks(cast<DeclContext>(D), WL); 307f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 3083702af57e399448efa8e2bfd600f009945b5c936Zhongxing Xu for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I) 309fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek for (llvm::SmallVectorImpl<Decl*>::iterator WI=WL.begin(), WE=WL.end(); 310fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek WI != WE; ++WI) 311fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek (*I)(*this, *Mgr, *WI); 312f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek} 313f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 314f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===// 315f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// Analyses 316f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===// 317f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 3181d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionWarnDeadStores(AnalysisConsumer &C, AnalysisManager& mgr, 3191d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek Decl *D) { 320b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu if (LiveVariables *L = mgr.getLiveVariables(D)) { 3217032f460fc9828f386056e75933da5af61e88638Ted Kremenek BugReporter BR(mgr); 322b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu CheckDeadStores(*mgr.getCFG(D), *L, mgr.getParentMap(D), BR); 3237032f460fc9828f386056e75933da5af61e88638Ted Kremenek } 324f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek} 325f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 3261d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionWarnUninitVals(AnalysisConsumer &C, AnalysisManager& mgr, 3271d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek Decl *D) { 3281d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek if (CFG* c = mgr.getCFG(D)) { 3295032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu CheckUninitializedValues(*c, mgr.getASTContext(), mgr.getDiagnostic()); 3301d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek } 331f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek} 332f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 333b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek 334d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisstatic void ActionExprEngine(AnalysisConsumer &C, AnalysisManager& mgr, 335f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek Decl *D, 336d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis TransferFuncs* tf) { 3371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 338d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis llvm::OwningPtr<TransferFuncs> TF(tf); 3397032f460fc9828f386056e75933da5af61e88638Ted Kremenek 34075d03cffe20b5c945ef04eba208efb0437339997Ted Kremenek // Construct the analysis engine. We first query for the LiveVariables 34175d03cffe20b5c945ef04eba208efb0437339997Ted Kremenek // information to see if the CFG is valid. 34275d03cffe20b5c945ef04eba208efb0437339997Ted Kremenek // FIXME: Inter-procedural analysis will need to handle invalid CFGs. 34375d03cffe20b5c945ef04eba208efb0437339997Ted Kremenek if (!mgr.getLiveVariables(D)) 344f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek return; 345d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis ExprEngine Eng(mgr, TF.take()); 346f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 3478382cf57b722f130f1a6b45380639871c07271c1Ted Kremenek if (C.Opts.EnableExperimentalInternalChecks) 3488382cf57b722f130f1a6b45380639871c07271c1Ted Kremenek RegisterExperimentalInternalChecks(Eng); 349f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 3506a19832d08f00ac78c0a69c4fbe38b04a55b75ccTed Kremenek RegisterAppleChecks(Eng, *D); 351f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 352eb94113be0ee5f4d38408b413d92464a0bc16b55Ted Kremenek if (C.Opts.EnableExperimentalChecks) 353eb94113be0ee5f4d38408b413d92464a0bc16b55Ted Kremenek RegisterExperimentalChecks(Eng); 354f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 355bd5a94e263137dc3ce7c100485626bae025cf58eArgyrios Kyrtzidis if (C.Opts.ObjCSelfInitCheck && isa<ObjCMethodDecl>(D)) 356bd5a94e263137dc3ce7c100485626bae025cf58eArgyrios Kyrtzidis registerObjCSelfInitChecker(Eng); 357bd5a94e263137dc3ce7c100485626bae025cf58eArgyrios Kyrtzidis 3581fafd1d96419f587763d1b81332d8f476aeace2eTom Care // Enable idempotent operation checking if it was explicitly turned on, or if 3591fafd1d96419f587763d1b81332d8f476aeace2eTom Care // we are running experimental checks (i.e. everything) 3601fafd1d96419f587763d1b81332d8f476aeace2eTom Care if (C.Opts.IdempotentOps || C.Opts.EnableExperimentalChecks 3611fafd1d96419f587763d1b81332d8f476aeace2eTom Care || C.Opts.EnableExperimentalInternalChecks) 3621fafd1d96419f587763d1b81332d8f476aeace2eTom Care RegisterIdempotentOperationChecker(Eng); 363c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek 364c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek if (C.Opts.BufferOverflows) 365c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek RegisterArrayBoundCheckerV2(Eng); 3661fafd1d96419f587763d1b81332d8f476aeace2eTom Care 36752d861ce41ce84d8389495ea78d97bcc962ac5baTom Care // Enable AnalyzerStatsChecker if it was given as an argument 36852d861ce41ce84d8389495ea78d97bcc962ac5baTom Care if (C.Opts.AnalyzerStats) 36952d861ce41ce84d8389495ea78d97bcc962ac5baTom Care RegisterAnalyzerStatsChecker(Eng); 37052d861ce41ce84d8389495ea78d97bcc962ac5baTom Care 371f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek // Set the graph auditor. 372c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu llvm::OwningPtr<ExplodedNode::Auditor> Auditor; 373f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek if (mgr.shouldVisualizeUbigraph()) { 374f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek Auditor.reset(CreateUbiViz()); 375c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu ExplodedNode::SetAuditor(Auditor.get()); 376f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek } 3771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 378b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek // Execute the worklist algorithm. 379c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu Eng.ExecuteWorkList(mgr.getStackFrame(D, 0), mgr.getMaxNodes()); 3801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 381f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek // Release the auditor (if any) so that it doesn't monitor the graph 382f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek // created BugReporter. 383c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu ExplodedNode::SetAuditor(0); 3843df6421150271266b5a90fd4c6bfa6566c38c036Ted Kremenek 38534d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek // Visualize the exploded graph. 386f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek if (mgr.shouldVisualizeGraphviz()) 38734d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek Eng.ViewGraph(mgr.shouldTrimGraph()); 3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3893df6421150271266b5a90fd4c6bfa6566c38c036Ted Kremenek // Display warnings. 3903df6421150271266b5a90fd4c6bfa6566c38c036Ted Kremenek Eng.getBugReporter().FlushReports(); 391bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek} 392bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek 393565e465c6d0093f1bf8414b2cabdc842022385a9Ted Kremenekstatic void ActionObjCMemCheckerAux(AnalysisConsumer &C, AnalysisManager& mgr, 3941d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek Decl *D, bool GCEnabled) { 3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 396d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis TransferFuncs* TF = MakeCFRefCountTF(mgr.getASTContext(), 397bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek GCEnabled, 398bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek mgr.getLangOptions()); 3991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 400d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis ActionExprEngine(C, mgr, D, TF); 401b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek} 402b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek 403565e465c6d0093f1bf8414b2cabdc842022385a9Ted Kremenekstatic void ActionObjCMemChecker(AnalysisConsumer &C, AnalysisManager& mgr, 4041d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek Decl *D) { 4051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 406b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek switch (mgr.getLangOptions().getGCMode()) { 407b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump default: 408b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump assert (false && "Invalid GC mode."); 409b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump case LangOptions::NonGC: 410565e465c6d0093f1bf8414b2cabdc842022385a9Ted Kremenek ActionObjCMemCheckerAux(C, mgr, D, false); 411b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump break; 412b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump 413b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump case LangOptions::GCOnly: 414565e465c6d0093f1bf8414b2cabdc842022385a9Ted Kremenek ActionObjCMemCheckerAux(C, mgr, D, true); 415b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump break; 416b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump 417b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump case LangOptions::HybridGC: 418565e465c6d0093f1bf8414b2cabdc842022385a9Ted Kremenek ActionObjCMemCheckerAux(C, mgr, D, false); 419565e465c6d0093f1bf8414b2cabdc842022385a9Ted Kremenek ActionObjCMemCheckerAux(C, mgr, D, true); 420b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump break; 421b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek } 422b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek} 423b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek 4241d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionDisplayLiveVariables(AnalysisConsumer &C, 4251d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek AnalysisManager& mgr, Decl *D) { 426b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu if (LiveVariables* L = mgr.getLiveVariables(D)) { 4277032f460fc9828f386056e75933da5af61e88638Ted Kremenek L->dumpBlockLiveness(mgr.getSourceManager()); 4287032f460fc9828f386056e75933da5af61e88638Ted Kremenek } 429235e031e84dd9d9aeee554db40e480f14650b527Ted Kremenek} 430235e031e84dd9d9aeee554db40e480f14650b527Ted Kremenek 4311d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionCFGDump(AnalysisConsumer &C, AnalysisManager& mgr, Decl *D) { 4321d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek if (CFG *cfg = mgr.getCFG(D)) { 4331d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek cfg->dump(mgr.getLangOptions()); 4347032f460fc9828f386056e75933da5af61e88638Ted Kremenek } 435902141f74ac3a2cd41966a98cd43e8702bc05ce9Ted Kremenek} 436902141f74ac3a2cd41966a98cd43e8702bc05ce9Ted Kremenek 4371d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionCFGView(AnalysisConsumer &C, AnalysisManager& mgr, Decl *D) { 4381d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek if (CFG *cfg = mgr.getCFG(D)) { 4391d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek cfg->viewCFG(mgr.getLangOptions()); 4407032f460fc9828f386056e75933da5af61e88638Ted Kremenek } 441902141f74ac3a2cd41966a98cd43e8702bc05ce9Ted Kremenek} 442902141f74ac3a2cd41966a98cd43e8702bc05ce9Ted Kremenek 4431d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionSecuritySyntacticChecks(AnalysisConsumer &C, 4441d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek AnalysisManager &mgr, Decl *D) { 4451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump BugReporter BR(mgr); 446b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu CheckSecuritySyntaxOnly(D, BR); 447dbfb5f853547c4cc2b4b39e90f01537dd317457aTed Kremenek} 448dbfb5f853547c4cc2b4b39e90f01537dd317457aTed Kremenek 4496dd66ed959b7f60749dd0040507b3f304183a1b6Ted Kremenekstatic void ActionLLVMConventionChecker(AnalysisConsumer &C, 4506dd66ed959b7f60749dd0040507b3f304183a1b6Ted Kremenek AnalysisManager &mgr, 451676ca153e04b1c6be477bc8a10f1e06256850ceeTed Kremenek TranslationUnitDecl &TU) { 4526dd66ed959b7f60749dd0040507b3f304183a1b6Ted Kremenek BugReporter BR(mgr); 453676ca153e04b1c6be477bc8a10f1e06256850ceeTed Kremenek CheckLLVMConventions(TU, BR); 4546dd66ed959b7f60749dd0040507b3f304183a1b6Ted Kremenek} 4556dd66ed959b7f60749dd0040507b3f304183a1b6Ted Kremenek 4561d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionWarnObjCDealloc(AnalysisConsumer &C, AnalysisManager& mgr, 4571d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek Decl *D) { 4584f4e7e4610f7a6eb8923a3bf6f2951b2dca98608Ted Kremenek if (mgr.getLangOptions().getGCMode() == LangOptions::GCOnly) 4594f4e7e4610f7a6eb8923a3bf6f2951b2dca98608Ted Kremenek return; 460db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek BugReporter BR(mgr); 4611d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek CheckObjCDealloc(cast<ObjCImplementationDecl>(D), mgr.getLangOptions(), BR); 462db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek} 463db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek 4641d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionWarnObjCUnusedIvars(AnalysisConsumer &C, AnalysisManager& mgr, 4651d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek Decl *D) { 466395aaf20d6e1ab04741562dc6b7d47164bcbd87eTed Kremenek BugReporter BR(mgr); 4671d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek CheckObjCUnusedIvar(cast<ObjCImplementationDecl>(D), BR); 468395aaf20d6e1ab04741562dc6b7d47164bcbd87eTed Kremenek} 469395aaf20d6e1ab04741562dc6b7d47164bcbd87eTed Kremenek 4701d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionWarnObjCMethSigs(AnalysisConsumer &C, AnalysisManager& mgr, 4711d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek Decl *D) { 4720d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek BugReporter BR(mgr); 473b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu CheckObjCInstMethSignature(cast<ObjCImplementationDecl>(D), BR); 4740d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek} 4750d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek 4761d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionWarnSizeofPointer(AnalysisConsumer &C, AnalysisManager &mgr, 4771d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek Decl *D) { 47828a109f63506d8c96e3fbf1b959b603ccec2f586Zhongxing Xu BugReporter BR(mgr); 47928a109f63506d8c96e3fbf1b959b603ccec2f586Zhongxing Xu CheckSizeofPointer(D, BR); 48028a109f63506d8c96e3fbf1b959b603ccec2f586Zhongxing Xu} 48128a109f63506d8c96e3fbf1b959b603ccec2f586Zhongxing Xu 482f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===// 483f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// AnalysisConsumer creation. 484f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===// 485f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 4869ef6537a894c33003359b1f9b9676e9178e028b7Ted KremenekASTConsumer* ento::CreateAnalysisConsumer(const Preprocessor& pp, 487e71b85feb0a2df9273b1b488f5b40279369a6255Eli Friedman const std::string& OutDir, 488e71b85feb0a2df9273b1b488f5b40279369a6255Eli Friedman const AnalyzerOptions& Opts) { 489efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar llvm::OwningPtr<AnalysisConsumer> C(new AnalysisConsumer(pp, OutDir, Opts)); 490be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek 491e71b85feb0a2df9273b1b488f5b40279369a6255Eli Friedman for (unsigned i = 0; i < Opts.AnalysisList.size(); ++i) 492e71b85feb0a2df9273b1b488f5b40279369a6255Eli Friedman switch (Opts.AnalysisList[i]) { 493f7f3c20a5d4c5bd1857a6cea1f001bb775401e96Ted Kremenek#define ANALYSIS(NAME, CMD, DESC, SCOPE)\ 494b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump case NAME:\ 495b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump C->add ## SCOPE ## Action(&Action ## NAME);\ 496b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump break; 4974df2c42581280bb1a02a5d034dbf657514cc56e8Eli Friedman#include "clang/Frontend/Analyses.def" 498b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump default: break; 499f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek } 5001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5012c4036eda90fad6d219d9f3fadbd9288fa197e89Ted Kremenek // Last, disable the effects of '-Werror' when using the AnalysisConsumer. 502efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar pp.getDiagnostics().setWarningsAsErrors(false); 503be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek 504f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek return C.take(); 505f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek} 506f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 507f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek//===----------------------------------------------------------------------===// 508f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek// Ubigraph Visualization. FIXME: Move to separate file. 509f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek//===----------------------------------------------------------------------===// 510f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 511f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremeneknamespace { 5121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 513c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xuclass UbigraphViz : public ExplodedNode::Auditor { 514f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek llvm::OwningPtr<llvm::raw_ostream> Out; 515710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek llvm::sys::Path Dir, Filename; 516f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek unsigned Cntr; 517f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 518f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek typedef llvm::DenseMap<void*,unsigned> VMap; 519f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek VMap M; 5201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 521f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenekpublic: 522710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek UbigraphViz(llvm::raw_ostream* out, llvm::sys::Path& dir, 52356b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek llvm::sys::Path& filename); 5241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 525710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek ~UbigraphViz(); 5261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump virtual void AddEdge(ExplodedNode* Src, ExplodedNode* Dst); 528f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek}; 5291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 530f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek} // end anonymous namespace 531f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 532c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xustatic ExplodedNode::Auditor* CreateUbiViz() { 533f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek std::string ErrMsg; 5341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 535710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek llvm::sys::Path Dir = llvm::sys::Path::GetTemporaryDirectory(&ErrMsg); 536f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek if (!ErrMsg.empty()) 537f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek return 0; 538f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 539710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek llvm::sys::Path Filename = Dir; 540f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek Filename.appendComponent("llvm_ubi"); 541f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek Filename.makeUnique(true,&ErrMsg); 542f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 543f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek if (!ErrMsg.empty()) 544f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek return 0; 545f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 546d57a7ef9252964bc6c8471451d7bd395b0520cb8Chris Lattner llvm::errs() << "Writing '" << Filename.str() << "'.\n"; 5471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 548f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek llvm::OwningPtr<llvm::raw_fd_ostream> Stream; 549b044c473a155b7e827680635c1699cb2b5b6c0eeDan Gohman Stream.reset(new llvm::raw_fd_ostream(Filename.c_str(), ErrMsg)); 550f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 551f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek if (!ErrMsg.empty()) 552f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek return 0; 5531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 554710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek return new UbigraphViz(Stream.take(), Dir, Filename); 555f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek} 556f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 557c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xuvoid UbigraphViz::AddEdge(ExplodedNode* Src, ExplodedNode* Dst) { 5581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 55945479c88c8a44c55d27c3bd855273bb318082f37Ted Kremenek assert (Src != Dst && "Self-edges are not allowed."); 5601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 561f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek // Lookup the Src. If it is a new node, it's a root. 562f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek VMap::iterator SrcI= M.find(Src); 563f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek unsigned SrcID; 5641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 565f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek if (SrcI == M.end()) { 566f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek M[Src] = SrcID = Cntr++; 567f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek *Out << "('vertex', " << SrcID << ", ('color','#00ff00'))\n"; 568f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek } 569f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek else 570f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek SrcID = SrcI->second; 5711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 572f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek // Lookup the Dst. 573f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek VMap::iterator DstI= M.find(Dst); 574f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek unsigned DstID; 575f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 576f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek if (DstI == M.end()) { 577f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek M[Dst] = DstID = Cntr++; 578f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek *Out << "('vertex', " << DstID << ")\n"; 579f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek } 58056b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek else { 58156b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek // We have hit DstID before. Change its style to reflect a cache hit. 582f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek DstID = DstI->second; 58356b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek *Out << "('change_vertex_style', " << DstID << ", 1)\n"; 58456b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek } 585f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 586f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek // Add the edge. 5871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump *Out << "('edge', " << SrcID << ", " << DstID 588d1289327f7d2126d732e23cc189ecd0aa5d07cbbTed Kremenek << ", ('arrow','true'), ('oriented', 'true'))\n"; 589f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek} 590f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 59156b98719b0dbebb33cb228afa888c47156be2381Ted KremenekUbigraphViz::UbigraphViz(llvm::raw_ostream* out, llvm::sys::Path& dir, 59256b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek llvm::sys::Path& filename) 59356b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek : Out(out), Dir(dir), Filename(filename), Cntr(0) { 59456b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek 59556b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n"; 59656b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," 59756b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek " ('size', '1.5'))\n"; 59856b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek} 59956b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek 600710ad9343f32b33b336369b20edad1a21a0b3299Ted KremenekUbigraphViz::~UbigraphViz() { 601710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek Out.reset(0); 6026cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer llvm::errs() << "Running 'ubiviz' program... "; 603710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek std::string ErrMsg; 604710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek llvm::sys::Path Ubiviz = llvm::sys::Program::FindProgramByName("ubiviz"); 605710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek std::vector<const char*> args; 606710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek args.push_back(Ubiviz.c_str()); 607710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek args.push_back(Filename.c_str()); 608710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek args.push_back(0); 6091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 610710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek if (llvm::sys::Program::ExecuteAndWait(Ubiviz, &args[0],0,0,0,0,&ErrMsg)) { 6116cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer llvm::errs() << "Error viewing graph: " << ErrMsg << "\n"; 612710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek } 6131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 614710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek // Delete the directory. 6151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Dir.eraseFromDisk(true); 616932680ecdeab4c216ce7c0736093d3dcd2f60f6dDaniel Dunbar} 617