diff options
| author | Ted Kremenek <kremenek@apple.com> | 2011-01-20 17:09:48 +0000 |
|---|---|---|
| committer | Ted Kremenek <kremenek@apple.com> | 2011-01-20 17:09:48 +0000 |
| commit | a1ec4f39f4637b3edf0e67e649b2e85003062101 (patch) | |
| tree | 20339f0b5bca54931e03536068313459da0bb8ae | |
| parent | 56d7eae8570f474a95d8feb54fe9307736c5f3f7 (diff) | |
| download | bcm5719-llvm-a1ec4f39f4637b3edf0e67e649b2e85003062101.tar.gz bcm5719-llvm-a1ec4f39f4637b3edf0e67e649b2e85003062101.zip | |
Enhance AnalysisConsumer to also visit functions
and methods defined within 'namespace X { ... }'.
llvm-svn: 123921
| -rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/AnalysisConsumer.cpp | 86 | ||||
| -rw-r--r-- | clang/test/Analysis/dead-stores.cpp | 12 |
2 files changed, 59 insertions, 39 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Checkers/AnalysisConsumer.cpp index ee4eae2ebfa..ae8732a857b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/AnalysisConsumer.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/AnalysisConsumer.cpp @@ -198,6 +198,8 @@ public: } virtual void HandleTranslationUnit(ASTContext &C); + void HandleDeclContext(ASTContext &C, DeclContext *dc); + void HandleCode(Decl *D, Actions& actions); }; } // end anonymous namespace @@ -206,55 +208,61 @@ public: // AnalysisConsumer implementation. //===----------------------------------------------------------------------===// -void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) { - - TranslationUnitDecl *TU = C.getTranslationUnitDecl(); - - for (DeclContext::decl_iterator I = TU->decls_begin(), E = TU->decls_end(); +void AnalysisConsumer::HandleDeclContext(ASTContext &C, DeclContext *dc) { + for (DeclContext::decl_iterator I = dc->decls_begin(), E = dc->decls_end(); I != E; ++I) { Decl *D = *I; - + switch (D->getKind()) { - case Decl::CXXConstructor: - case Decl::CXXDestructor: - case Decl::CXXConversion: - case Decl::CXXMethod: - case Decl::Function: { - FunctionDecl* FD = cast<FunctionDecl>(D); - // We skip function template definitions, as their semantics is - // only determined when they are instantiated. - if (FD->isThisDeclarationADefinition() && - !FD->isDependentContext()) { - if (!Opts.AnalyzeSpecificFunction.empty() && - FD->getDeclName().getAsString() != Opts.AnalyzeSpecificFunction) - break; - DisplayFunction(FD); - HandleCode(FD, FunctionActions); + case Decl::Namespace: { + HandleDeclContext(C, cast<NamespaceDecl>(D)); + break; } - break; - } - - case Decl::ObjCImplementation: { - ObjCImplementationDecl* ID = cast<ObjCImplementationDecl>(*I); - HandleCode(ID, ObjCImplementationActions); - - for (ObjCImplementationDecl::method_iterator MI = ID->meth_begin(), - ME = ID->meth_end(); MI != ME; ++MI) { - if ((*MI)->isThisDeclarationADefinition()) { + case Decl::CXXConstructor: + case Decl::CXXDestructor: + case Decl::CXXConversion: + case Decl::CXXMethod: + case Decl::Function: { + FunctionDecl* FD = cast<FunctionDecl>(D); + // We skip function template definitions, as their semantics is + // only determined when they are instantiated. + if (FD->isThisDeclarationADefinition() && + !FD->isDependentContext()) { if (!Opts.AnalyzeSpecificFunction.empty() && - Opts.AnalyzeSpecificFunction != (*MI)->getSelector().getAsString()) + FD->getDeclName().getAsString() != Opts.AnalyzeSpecificFunction) break; - DisplayFunction(*MI); - HandleCode(*MI, ObjCMethodActions); + DisplayFunction(FD); + HandleCode(FD, FunctionActions); } + break; } - break; + + case Decl::ObjCImplementation: { + ObjCImplementationDecl* ID = cast<ObjCImplementationDecl>(*I); + HandleCode(ID, ObjCImplementationActions); + + for (ObjCImplementationDecl::method_iterator MI = ID->meth_begin(), + ME = ID->meth_end(); MI != ME; ++MI) { + if ((*MI)->isThisDeclarationADefinition()) { + if (!Opts.AnalyzeSpecificFunction.empty() && + Opts.AnalyzeSpecificFunction != (*MI)->getSelector().getAsString()) + break; + DisplayFunction(*MI); + HandleCode(*MI, ObjCMethodActions); + } + } + break; + } + + default: + break; } + } +} - default: - break; - } - } +void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) { + TranslationUnitDecl *TU = C.getTranslationUnitDecl(); + HandleDeclContext(C, TU); for (TUActions::iterator I = TranslationUnitActions.begin(), E = TranslationUnitActions.end(); I != E; ++I) { diff --git a/clang/test/Analysis/dead-stores.cpp b/clang/test/Analysis/dead-stores.cpp index b21ffad6c5f..b5fc05028f7 100644 --- a/clang/test/Analysis/dead-stores.cpp +++ b/clang/test/Analysis/dead-stores.cpp @@ -100,3 +100,15 @@ static void test_new(unsigned n) { char **p = new char* [n]; // expected-warning{{never read}} } +//===----------------------------------------------------------------------===// +// Dead stores in namespaces. +//===----------------------------------------------------------------------===// + +namespace foo { + int test_4(int x) { + x = 2; // expected-warning{{Value stored to 'x' is never read}} + x = 2; + return x; + } +} + |

