From: Zhongxing Xu Date: Thu, 6 May 2010 02:59:29 +0000 (+0000) Subject: Make -analyzer-inline-call not a separate analysis. Instead it's a boolean X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7b99d12b4ca67fccdf5090761ba257732e954e75;p=clang Make -analyzer-inline-call not a separate analysis. Instead it's a boolean flag now, and can be used with other analyses. Only turned it on for C++ methods for now. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103160 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Checker/PathSensitive/AnalysisManager.h b/include/clang/Checker/PathSensitive/AnalysisManager.h index 0c59d7b572..9194f45899 100644 --- a/include/clang/Checker/PathSensitive/AnalysisManager.h +++ b/include/clang/Checker/PathSensitive/AnalysisManager.h @@ -52,19 +52,21 @@ class AnalysisManager : public BugReporterData { // bifurcates paths. bool EagerlyAssume; bool TrimGraph; + bool InlineCall; public: AnalysisManager(ASTContext &ctx, Diagnostic &diags, const LangOptions &lang, PathDiagnosticClient *pd, StoreManagerCreator storemgr, ConstraintManagerCreator constraintmgr, unsigned maxnodes, - bool vizdot, bool vizubi, bool purge, bool eager, bool trim) + bool vizdot, bool vizubi, bool purge, bool eager, bool trim, + bool inlinecall) : Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd), CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr), AScope(ScopeDecl), MaxNodes(maxnodes), VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge), - EagerlyAssume(eager), TrimGraph(trim) {} + EagerlyAssume(eager), TrimGraph(trim), InlineCall(inlinecall) {} ~AnalysisManager() { FlushDiagnostics(); } @@ -122,6 +124,8 @@ public: bool shouldEagerlyAssume() const { return EagerlyAssume; } + bool shouldInlineCall() const { return InlineCall; } + CFG *getCFG(Decl const *D) { return AnaCtxMgr.getContext(D)->getCFG(); } diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 8e8eacb9c3..9ac6ad39eb 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -56,8 +56,6 @@ def analysis_ObjCMemChecker : Flag<"-analyzer-check-objc-mem">, HelpText<"Run the [Core] Foundation reference count checker">; 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 inlining callees when its definition is available.">; def analyzer_store : Separate<"-analyzer-store">, HelpText<"Source Code Analysis - Abstract Memory Store Models">; @@ -97,6 +95,8 @@ def analyzer_viz_egraph_graphviz : Flag<"-analyzer-viz-egraph-graphviz">, HelpText<"Display exploded graph using GraphViz">; def analyzer_viz_egraph_ubigraph : Flag<"-analyzer-viz-egraph-ubigraph">, HelpText<"Display exploded graph using Ubigraph">; +def analyzer_inline_call : Flag<"-analyzer-inline-call">, + HelpText<"Experimental transfer function inlining callees when its definition is available.">; def analyzer_max_nodes : Separate<"-analyzer-max-nodes">, HelpText<"The maximum number of nodes the analyzer can generate">; diff --git a/include/clang/Frontend/AnalysisConsumer.h b/include/clang/Frontend/AnalysisConsumer.h index 3341bb01f0..5dd80142ee 100644 --- a/include/clang/Frontend/AnalysisConsumer.h +++ b/include/clang/Frontend/AnalysisConsumer.h @@ -71,6 +71,8 @@ public: unsigned VisualizeEGUbi : 1; unsigned EnableExperimentalChecks : 1; unsigned EnableExperimentalInternalChecks : 1; + unsigned InlineCall : 1; + public: AnalyzerOptions() { AnalysisStoreOpt = BasicStoreModel; diff --git a/lib/Checker/GRCXXExprEngine.cpp b/lib/Checker/GRCXXExprEngine.cpp index 00ac995592..18e112cc8d 100644 --- a/lib/Checker/GRCXXExprEngine.cpp +++ b/lib/Checker/GRCXXExprEngine.cpp @@ -86,7 +86,7 @@ void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest, const CXXConstructorDecl *CD = E->getConstructor(); assert(CD); - if (!CD->isThisDeclarationADefinition()) + if (!(CD->isThisDeclarationADefinition() && AMgr.shouldInlineCall())) // FIXME: invalidate the object. return; @@ -147,7 +147,7 @@ void GRExprEngine::VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, const CXXMethodDecl *MD = cast(ME->getMemberDecl()); assert(MD && "not a CXXMethodDecl?"); - if (!MD->isThisDeclarationADefinition()) + if (!(MD->isThisDeclarationADefinition() && AMgr.shouldInlineCall())) // FIXME: conservative method call evaluation. return; diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp index 87c3fca249..df74eadaa0 100644 --- a/lib/Frontend/AnalysisConsumer.cpp +++ b/lib/Frontend/AnalysisConsumer.cpp @@ -177,7 +177,7 @@ public: Opts.MaxNodes, Opts.VisualizeEGDot, Opts.VisualizeEGUbi, Opts.PurgeDead, Opts.EagerlyAssume, - Opts.TrimGraph)); + Opts.TrimGraph, Opts.InlineCall)); } virtual void HandleTranslationUnit(ASTContext &C); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index e1275c16fe..92f33d01be 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -797,6 +797,7 @@ static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, Args.hasArg(OPT_analyzer_experimental_internal_checks); Opts.TrimGraph = Args.hasArg(OPT_trim_egraph); Opts.MaxNodes = getLastArgIntValue(Args, OPT_analyzer_max_nodes,150000,Diags); + Opts.InlineCall = Args.hasArg(OPT_analyzer_inline_call); } static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, diff --git a/test/Analysis/method-call.cpp b/test/Analysis/method-call.cpp index dd891596c5..47f14447d6 100644 --- a/test/Analysis/method-call.cpp +++ b/test/Analysis/method-call.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store region -verify %s +// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-inline-call -analyzer-store region -verify %s struct A { int x; A(int a) { x = a; }