From fc576514d06c46a7cac49500169411d82f38d04b Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 7 Dec 2009 22:06:12 +0000 Subject: [PATCH] Add clang-cc option '-analyzer-opt-analyze-nested-blocks' to treat block literals as an entry point for analyzer checks. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90810 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Driver/CC1Options.td | 4 ++- include/clang/Frontend/AnalysisConsumer.h | 2 ++ lib/Frontend/AnalysisConsumer.cpp | 41 ++++++++++++++++++----- lib/Frontend/CompilerInvocation.cpp | 6 +++- 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 582b9c28ac..aa4d3bfadc 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -55,7 +55,7 @@ def analysis_CheckerCFRef : Flag<"-checker-cfref">, def analysis_WarnSizeofPointer : Flag<"-warn-sizeof-pointer">, HelpText<"Warn about unintended use of sizeof() on pointer expressions">; def analysis_InlineCall : Flag<"-inline-call">, - HelpText<"Experimental transfer function inling callees when its definition is available.">; + HelpText<"Experimental transfer function inlining callees when its definition is available.">; def analyzer_store : Separate<"-analyzer-store">, HelpText<"Source Code Analysis - Abstract Memory Store Models">; @@ -73,6 +73,8 @@ def analyzer_output_EQ : Joined<"-analyzer-output=">, def analyzer_opt_analyze_headers : Flag<"-analyzer-opt-analyze-headers">, HelpText<"Force the static analyzer to analyze functions defined in header files">; +def analyzer_opt_analyze_nested_blocks : Flag<"-analyzer-opt-analyze-nested-blocks">, + HelpText<"Analyze the definitions of blocks in addition to functions">; def analyzer_display_progress : Flag<"-analyzer-display-progress">, HelpText<"Emit verbose output about the analyzer's progress">; def analyzer_experimental_checks : Flag<"-analyzer-experimental-checks">, diff --git a/include/clang/Frontend/AnalysisConsumer.h b/include/clang/Frontend/AnalysisConsumer.h index 24fed6e76a..f55e5dc040 100644 --- a/include/clang/Frontend/AnalysisConsumer.h +++ b/include/clang/Frontend/AnalysisConsumer.h @@ -62,6 +62,7 @@ public: std::string AnalyzeSpecificFunction; unsigned AnalyzeAll : 1; unsigned AnalyzerDisplayProgress : 1; + unsigned AnalyzeNestedBlocks : 1; unsigned EagerlyAssume : 1; unsigned PurgeDead : 1; unsigned TrimGraph : 1; @@ -76,6 +77,7 @@ public: AnalysisDiagOpt = PD_HTML; AnalyzeAll = 0; AnalyzerDisplayProgress = 0; + AnalyzeNestedBlocks = 0; EagerlyAssume = 0; PurgeDead = 1; TrimGraph = 0; diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp index 5df1eceb88..92f34b21fe 100644 --- a/lib/Frontend/AnalysisConsumer.cpp +++ b/lib/Frontend/AnalysisConsumer.cpp @@ -139,14 +139,21 @@ public: return; declDisplayed = true; - // FIXME: Is getCodeDecl() always a named decl? - if (isa(D) || isa(D)) { - const NamedDecl *ND = cast(D); - SourceManager &SM = Mgr->getASTContext().getSourceManager(); - llvm::errs() << "ANALYZE: " - << SM.getPresumedLoc(ND->getLocation()).getFilename() - << ' ' << ND->getNameAsString() << '\n'; + SourceManager &SM = Mgr->getASTContext().getSourceManager(); + PresumedLoc Loc = SM.getPresumedLoc(D->getLocation()); + llvm::errs() << "ANALYZE: " << Loc.getFilename(); + + if (const NamedDecl *ND = dyn_cast(D)) { + assert(isa(D) || isa(D)); + llvm::errs() << ' ' << ND->getNameAsString(); + } + else { + assert(isa(D)); + llvm::errs() << ' ' << "block(line:" << Loc.getLine() << ",col:" + << Loc.getColumn(); } + + llvm::errs() << '\n'; } void addCodeAction(CodeAction action) { @@ -269,6 +276,16 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) { Mgr.reset(NULL); } +static void FindBlocks(DeclContext *D, llvm::SmallVectorImpl &WL) { + if (BlockDecl *BD = dyn_cast(D)) + WL.push_back(BD); + + for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end(); + I!=E; ++I) + if (DeclContext *DC = dyn_cast(*I)) + FindBlocks(DC, WL); +} + void AnalysisConsumer::HandleCode(Decl *D, Stmt* Body, Actions& actions) { // Don't run the actions if an error has occured with parsing the file. @@ -285,8 +302,16 @@ void AnalysisConsumer::HandleCode(Decl *D, Stmt* Body, Actions& actions) { Mgr->ClearContexts(); // Dispatch on the actions. + llvm::SmallVector WL; + WL.push_back(D); + + if (Opts.AnalyzeNestedBlocks) + FindBlocks(cast(D), WL); + for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I) - (*I)(*this, *Mgr, D); + for (llvm::SmallVectorImpl::iterator WI=WL.begin(), WE=WL.end(); + WI != WE; ++WI) + (*I)(*this, *Mgr, *WI); } //===----------------------------------------------------------------------===// diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 2ecbcfe862..1f64e1e7fa 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -31,7 +31,7 @@ using namespace clang; static const char *getAnalysisName(Analyses Kind) { switch (Kind) { default: - llvm::llvm_unreachable("Unknown analysis store!"); + llvm::llvm_unreachable("Unknown analysis kind!"); #define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)\ case NAME: return "-" CMDFLAG; #include "clang/Frontend/Analyses.def" @@ -96,6 +96,8 @@ static void AnalyzerOptsToArgs(const AnalyzerOptions &Opts, Res.push_back("-analyzer-opt-analyze-headers"); if (Opts.AnalyzerDisplayProgress) Res.push_back("-analyzer-display-progress"); + if (Opts.AnalyzeNestedBlocks) + Res.push_back("-analyzer-opt-analyze-nested-blocks"); if (Opts.EagerlyAssume) Res.push_back("-analyzer-eagerly-assume"); if (!Opts.PurgeDead) @@ -709,6 +711,8 @@ static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, Opts.VisualizeEGUbi = Args.hasArg(OPT_analyzer_viz_egraph_ubigraph); Opts.AnalyzeAll = Args.hasArg(OPT_analyzer_opt_analyze_headers); Opts.AnalyzerDisplayProgress = Args.hasArg(OPT_analyzer_display_progress); + Opts.AnalyzeNestedBlocks = + Args.hasArg(OPT_analyzer_opt_analyze_nested_blocks); Opts.PurgeDead = !Args.hasArg(OPT_analyzer_no_purge_dead); Opts.EagerlyAssume = Args.hasArg(OPT_analyzer_eagerly_assume); Opts.AnalyzeSpecificFunction = getLastArgValue(Args, OPT_analyze_function); -- 2.40.0