From ee30965ce96e0a7b04b1aa16df60e9ba8b0a33c9 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer <benny.kra@googlemail.com> Date: Sat, 17 Jul 2010 13:51:58 +0000 Subject: [PATCH] Revert r108617, it broke the build. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108621 91177308-0d34-0410-b5e6-96231b3b80d8 --- examples/wpa/clang-wpa.cpp | 4 +- include/clang/Analysis/AnalysisContext.h | 21 ++------ include/clang/Analysis/ProgramPoint.h | 12 ++--- .../Checker/PathSensitive/AnalysisManager.h | 37 ++----------- .../Checker/PathSensitive/GRCoreEngine.h | 10 ++-- lib/Analysis/AnalysisContext.cpp | 5 +- lib/Checker/AnalysisConsumer.cpp | 3 +- lib/Checker/CMakeLists.txt | 2 +- lib/Checker/CallInliner.cpp | 54 +++++++++++++++++++ lib/Checker/GRCXXExprEngine.cpp | 4 +- lib/Checker/GRCoreEngine.cpp | 10 +--- lib/Checker/GRExprEngine.cpp | 39 +++++--------- tools/driver/Makefile | 4 +- 13 files changed, 98 insertions(+), 107 deletions(-) create mode 100644 lib/Checker/CallInliner.cpp diff --git a/examples/wpa/clang-wpa.cpp b/examples/wpa/clang-wpa.cpp index 1caa3b9b68c..74ec368cfbe 100644 --- a/examples/wpa/clang-wpa.cpp +++ b/examples/wpa/clang-wpa.cpp @@ -129,7 +129,7 @@ int main(int argc, char **argv) { AnalysisManager AMgr(TU->getASTContext(), PP.getDiagnostics(), PP.getLangOptions(), /* PathDiagnostic */ 0, CreateRegionStoreManager, - CreateRangeConstraintManager, &Idxer, + CreateRangeConstraintManager, /* MaxNodes */ 300000, /* MaxLoop */ 3, /* VisualizeEG */ false, /* VisualizeEGUbi */ false, /* PurgeDead */ true, /* EagerlyAssume */ false, @@ -139,7 +139,7 @@ int main(int argc, char **argv) { AMgr.getLangOptions()); GRExprEngine Eng(AMgr, TF); - Eng.ExecuteWorkList(AMgr.getStackFrame(FD, TU), AMgr.getMaxNodes()); + Eng.ExecuteWorkList(AMgr.getStackFrame(FD), AMgr.getMaxNodes()); return 0; } diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h index 584173a33fb..9ebd93b75b3 100644 --- a/include/clang/Analysis/AnalysisContext.h +++ b/include/clang/Analysis/AnalysisContext.h @@ -34,16 +34,11 @@ class ImplicitParamDecl; class LocationContextManager; class StackFrameContext; -namespace idx { class TranslationUnit; } - /// AnalysisContext contains the context data for the function or method under /// analysis. class AnalysisContext { const Decl *D; - // TranslationUnit is NULL if we don't have multiple translation units. - const idx::TranslationUnit *TU; - // AnalysisContext owns the following data. CFG *cfg; bool builtCFG; @@ -53,18 +48,14 @@ class AnalysisContext { llvm::BumpPtrAllocator A; bool AddEHEdges; public: - AnalysisContext(const Decl *d, const idx::TranslationUnit *tu, - bool addehedges = false) - : D(d), TU(tu), cfg(0), builtCFG(false), liveness(0), PM(0), + AnalysisContext(const Decl *d, bool addehedges = false) + : D(d), cfg(0), builtCFG(false), liveness(0), PM(0), ReferencedBlockVars(0), AddEHEdges(addehedges) {} ~AnalysisContext(); ASTContext &getASTContext() { return D->getASTContext(); } - const Decl *getDecl() const { return D; } - - const idx::TranslationUnit *getTranslationUnit() const { return TU; } - + const Decl *getDecl() { return D; } /// getAddEHEdges - Return true iff we are adding exceptional edges from /// callExprs. If this is false, then try/catch statements and blocks /// reachable from them can appear to be dead in the CFG, analysis passes must @@ -91,7 +82,7 @@ class AnalysisContextManager { public: ~AnalysisContextManager(); - AnalysisContext *getContext(const Decl *D,const idx::TranslationUnit *TU = 0); + AnalysisContext *getContext(const Decl *D); // Discard all previously created AnalysisContexts. void clear(); @@ -118,10 +109,6 @@ public: AnalysisContext *getAnalysisContext() const { return Ctx; } - const idx::TranslationUnit *getTranslationUnit() const { - return Ctx->getTranslationUnit(); - } - const LocationContext *getParent() const { return Parent; } bool isParentOf(const LocationContext *LC) const; diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h index 24bbf226401..075838d45e5 100644 --- a/include/clang/Analysis/ProgramPoint.h +++ b/include/clang/Analysis/ProgramPoint.h @@ -15,7 +15,6 @@ #ifndef LLVM_CLANG_ANALYSIS_PROGRAM_POINT #define LLVM_CLANG_ANALYSIS_PROGRAM_POINT -#include "clang/Analysis/AnalysisContext.h" #include "clang/Analysis/CFG.h" #include "llvm/System/DataTypes.h" #include "llvm/ADT/DenseMap.h" @@ -27,7 +26,6 @@ namespace clang { class LocationContext; -class AnalysisContext; class FunctionDecl; class ProgramPoint { @@ -315,16 +313,16 @@ public: class CallEnter : public StmtPoint { public: - // L is caller's location context. AC is callee's AnalysisContext. - CallEnter(const Stmt *S, const AnalysisContext *AC, const LocationContext *L) - : StmtPoint(S, AC, CallEnterKind, L, 0) {} + // CallEnter uses the caller's location context. + CallEnter(const Stmt *S, const FunctionDecl *fd, const LocationContext *L) + : StmtPoint(S, fd, CallEnterKind, L, 0) {} const Stmt *getCallExpr() const { return static_cast<const Stmt *>(getData1()); } - const AnalysisContext *getCalleeContext() const { - return static_cast<const AnalysisContext *>(getData2()); + const FunctionDecl *getCallee() const { + return static_cast<const FunctionDecl *>(getData2()); } static bool classof(const ProgramPoint *Location) { diff --git a/include/clang/Checker/PathSensitive/AnalysisManager.h b/include/clang/Checker/PathSensitive/AnalysisManager.h index 3f673618cf6..3c7cb68c094 100644 --- a/include/clang/Checker/PathSensitive/AnalysisManager.h +++ b/include/clang/Checker/PathSensitive/AnalysisManager.h @@ -21,11 +21,6 @@ namespace clang { -namespace idx { - class Indexer; - class TranslationUnit; -} - class AnalysisManager : public BugReporterData { AnalysisContextManager AnaCtxMgr; LocationContextManager LocCtxMgr; @@ -40,11 +35,6 @@ class AnalysisManager : public BugReporterData { StoreManagerCreator CreateStoreMgr; ConstraintManagerCreator CreateConstraintMgr; - /// \brief Provide function definitions in other translation units. This is - /// NULL if we don't have multiple translation units. AnalysisManager does - /// not own the Indexer. - idx::Indexer *Idxer; - enum AnalysisScope { ScopeTU, ScopeDecl } AScope; // The maximum number of exploded nodes the analyzer will generate. @@ -72,14 +62,13 @@ public: AnalysisManager(ASTContext &ctx, Diagnostic &diags, const LangOptions &lang, PathDiagnosticClient *pd, StoreManagerCreator storemgr, - ConstraintManagerCreator constraintmgr, - idx::Indexer *idxer, - unsigned maxnodes, unsigned maxloop, + ConstraintManagerCreator constraintmgr, unsigned maxnodes, + unsigned maxloop, bool vizdot, bool vizubi, bool purge, bool eager, bool trim, bool inlinecall) : Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd), - CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),Idxer(idxer), + CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr), AScope(ScopeDecl), MaxNodes(maxnodes), MaxLoop(maxloop), VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge), EagerlyAssume(eager), TrimGraph(trim), InlineCall(inlinecall) {} @@ -144,10 +133,6 @@ public: bool shouldInlineCall() const { return InlineCall; } - bool hasIndexer() const { return Idxer != 0; } - - const AnalysisContext *getAnalysisContextInAnotherTU(const Decl *D); - CFG *getCFG(Decl const *D) { return AnaCtxMgr.getContext(D)->getCFG(); } @@ -160,21 +145,9 @@ public: return AnaCtxMgr.getContext(D)->getParentMap(); } - const AnalysisContext *getAnalysisContext(const Decl *D) { - return AnaCtxMgr.getContext(D); - } - - const StackFrameContext *getStackFrame(AnalysisContext *Ctx, - LocationContext const *Parent, - Stmt const *S, const CFGBlock *Blk, - unsigned Idx) { - return LocCtxMgr.getStackFrame(Ctx, Parent, S, Blk, Idx); - } - // Get the top level stack frame. - const StackFrameContext *getStackFrame(Decl const *D, - const idx::TranslationUnit *TU) { - return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D, TU), 0, 0, 0, 0); + const StackFrameContext *getStackFrame(Decl const *D) { + return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), 0, 0, 0, 0); } // Get a stack frame with parent. diff --git a/include/clang/Checker/PathSensitive/GRCoreEngine.h b/include/clang/Checker/PathSensitive/GRCoreEngine.h index 317558e962c..7f101dca97e 100644 --- a/include/clang/Checker/PathSensitive/GRCoreEngine.h +++ b/include/clang/Checker/PathSensitive/GRCoreEngine.h @@ -442,8 +442,8 @@ class GRCallEnterNodeBuilder { // The call site. const Stmt *CE; - // The AnalysisContext of the callee. - const AnalysisContext *CalleeCtx; + // The definition of callee. + const FunctionDecl *FD; // The parent block of the CallExpr. const CFGBlock *Block; @@ -453,9 +453,9 @@ class GRCallEnterNodeBuilder { public: GRCallEnterNodeBuilder(GRCoreEngine &eng, const ExplodedNode *pred, - const Stmt *s, const AnalysisContext *callee, + const Stmt *s, const FunctionDecl *fd, const CFGBlock *blk, unsigned idx) - : Eng(eng), Pred(pred), CE(s), CalleeCtx(callee), Block(blk), Index(idx) {} + : Eng(eng), Pred(pred), CE(s), FD(fd), Block(blk), Index(idx) {} const GRState *getState() const { return Pred->getState(); } @@ -465,7 +465,7 @@ public: const Stmt *getCallExpr() const { return CE; } - const AnalysisContext *getCalleeContext() const { return CalleeCtx; } + const FunctionDecl *getCallee() const { return FD; } const CFGBlock *getBlock() const { return Block; } diff --git a/lib/Analysis/AnalysisContext.cpp b/lib/Analysis/AnalysisContext.cpp index 538d559c16c..06d8aec3910 100644 --- a/lib/Analysis/AnalysisContext.cpp +++ b/lib/Analysis/AnalysisContext.cpp @@ -83,11 +83,10 @@ LiveVariables *AnalysisContext::getLiveVariables() { return liveness; } -AnalysisContext *AnalysisContextManager::getContext(const Decl *D, - const idx::TranslationUnit *TU) { +AnalysisContext *AnalysisContextManager::getContext(const Decl *D) { AnalysisContext *&AC = Contexts[D]; if (!AC) - AC = new AnalysisContext(D, TU); + AC = new AnalysisContext(D); return AC; } diff --git a/lib/Checker/AnalysisConsumer.cpp b/lib/Checker/AnalysisConsumer.cpp index bbeca312f09..6c7a294b1d8 100644 --- a/lib/Checker/AnalysisConsumer.cpp +++ b/lib/Checker/AnalysisConsumer.cpp @@ -173,7 +173,6 @@ public: Mgr.reset(new AnalysisManager(*Ctx, PP.getDiagnostics(), PP.getLangOptions(), PD, CreateStoreMgr, CreateConstraintMgr, - /* Indexer */ 0, Opts.MaxNodes, Opts.MaxLoop, Opts.VisualizeEGDot, Opts.VisualizeEGUbi, Opts.PurgeDead, Opts.EagerlyAssume, @@ -350,7 +349,7 @@ static void ActionGRExprEngine(AnalysisConsumer &C, AnalysisManager& mgr, } // Execute the worklist algorithm. - Eng.ExecuteWorkList(mgr.getStackFrame(D, 0), mgr.getMaxNodes()); + Eng.ExecuteWorkList(mgr.getStackFrame(D), mgr.getMaxNodes()); // Release the auditor (if any) so that it doesn't monitor the graph // created BugReporter. diff --git a/lib/Checker/CMakeLists.txt b/lib/Checker/CMakeLists.txt index c3dab228708..259346a9706 100644 --- a/lib/Checker/CMakeLists.txt +++ b/lib/Checker/CMakeLists.txt @@ -4,7 +4,6 @@ add_clang_library(clangChecker AdjustedReturnValueChecker.cpp AggExprVisitor.cpp AnalysisConsumer.cpp - AnalysisManager.cpp ArrayBoundChecker.cpp AttrNonNullChecker.cpp BasicConstraintManager.cpp @@ -16,6 +15,7 @@ add_clang_library(clangChecker BuiltinFunctionChecker.cpp CFRefCount.cpp CallAndMessageChecker.cpp + CallInliner.cpp CastSizeChecker.cpp CastToStructChecker.cpp CheckDeadStores.cpp diff --git a/lib/Checker/CallInliner.cpp b/lib/Checker/CallInliner.cpp new file mode 100644 index 00000000000..c47e06c78fb --- /dev/null +++ b/lib/Checker/CallInliner.cpp @@ -0,0 +1,54 @@ +//===--- CallInliner.cpp - Transfer function that inlines callee ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the callee inlining transfer function. +// +//===----------------------------------------------------------------------===// + +#include "clang/Checker/PathSensitive/CheckerVisitor.h" +#include "clang/Checker/PathSensitive/GRState.h" +#include "clang/Checker/Checkers/LocalCheckers.h" + +using namespace clang; + +namespace { +class CallInliner : public Checker { +public: + static void *getTag() { + static int x; + return &x; + } + + virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE); +}; +} + +void clang::RegisterCallInliner(GRExprEngine &Eng) { + Eng.registerCheck(new CallInliner()); +} + +bool CallInliner::EvalCallExpr(CheckerContext &C, const CallExpr *CE) { + const GRState *state = C.getState(); + const Expr *Callee = CE->getCallee(); + SVal L = state->getSVal(Callee); + + const FunctionDecl *FD = L.getAsFunctionDecl(); + if (!FD) + return false; + + if (!FD->hasBody(FD)) + return false; + + // Now we have the definition of the callee, create a CallEnter node. + CallEnter Loc(CE, FD, C.getPredecessor()->getLocationContext()); + C.addTransition(state, Loc); + + return true; +} + diff --git a/lib/Checker/GRCXXExprEngine.cpp b/lib/Checker/GRCXXExprEngine.cpp index 5c313318c1a..18e112cc8d3 100644 --- a/lib/Checker/GRCXXExprEngine.cpp +++ b/lib/Checker/GRCXXExprEngine.cpp @@ -104,7 +104,7 @@ void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest, const CXXThisRegion *ThisR = getCXXThisRegion(E->getConstructor(), SFC); - CallEnter Loc(E, SFC->getAnalysisContext(), Pred->getLocationContext()); + CallEnter Loc(E, CD, Pred->getLocationContext()); for (ExplodedNodeSet::iterator NI = ArgsEvaluated.begin(), NE = ArgsEvaluated.end(); NI != NE; ++NI) { const GRState *state = GetState(*NI); @@ -157,7 +157,7 @@ void GRExprEngine::VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, Builder->getBlock(), Builder->getIndex()); const CXXThisRegion *ThisR = getCXXThisRegion(MD, SFC); - CallEnter Loc(MCE, SFC->getAnalysisContext(), Pred->getLocationContext()); + CallEnter Loc(MCE, MD, Pred->getLocationContext()); for (ExplodedNodeSet::iterator I = AllArgsEvaluated.begin(), E = AllArgsEvaluated.end(); I != E; ++I) { // Set up 'this' region. diff --git a/lib/Checker/GRCoreEngine.cpp b/lib/Checker/GRCoreEngine.cpp index df790e304a4..a816186a307 100644 --- a/lib/Checker/GRCoreEngine.cpp +++ b/lib/Checker/GRCoreEngine.cpp @@ -227,8 +227,8 @@ bool GRCoreEngine::ExecuteWorkList(const LocationContext *L, unsigned Steps) { void GRCoreEngine::HandleCallEnter(const CallEnter &L, const CFGBlock *Block, unsigned Index, ExplodedNode *Pred) { - GRCallEnterNodeBuilder Builder(*this, Pred, L.getCallExpr(), - L.getCalleeContext(), Block, Index); + GRCallEnterNodeBuilder Builder(*this, Pred, L.getCallExpr(), L.getCallee(), + Block, Index); ProcessCallEnter(Builder); } @@ -692,12 +692,6 @@ void GREndPathNodeBuilder::GenerateCallExitNode(const GRState *state) { void GRCallEnterNodeBuilder::GenerateNode(const GRState *state, const LocationContext *LocCtx) { - // Check if the callee is in the same translation unit. - if (CalleeCtx->getTranslationUnit() != - Pred->getLocationContext()->getTranslationUnit()) { - assert(0 && "to be implemented"); - } - // Get the callee entry block. const CFGBlock *Entry = &(LocCtx->getCFG()->getEntry()); assert(Entry->empty()); diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp index ce7b9d8d8e9..26b5801068f 100644 --- a/lib/Checker/GRExprEngine.cpp +++ b/lib/Checker/GRExprEngine.cpp @@ -1441,12 +1441,12 @@ void GRExprEngine::ProcessSwitch(GRSwitchNodeBuilder& builder) { } void GRExprEngine::ProcessCallEnter(GRCallEnterNodeBuilder &B) { - const StackFrameContext *LocCtx - = AMgr.getStackFrame(const_cast<AnalysisContext *>(B.getCalleeContext()), - B.getLocationContext(), - B.getCallExpr(), - B.getBlock(), - B.getIndex()); + const FunctionDecl *FD = B.getCallee(); + const StackFrameContext *LocCtx = AMgr.getStackFrame(FD, + B.getLocationContext(), + B.getCallExpr(), + B.getBlock(), + B.getIndex()); const GRState *state = B.getState(); state = getStoreManager().EnterStackFrame(state, LocCtx); @@ -1886,29 +1886,16 @@ bool GRExprEngine::InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, if (!FD) return false; - // Check if the function definition is in the same translation unit. - if (FD->hasBody(FD)) { - // Now we have the definition of the callee, create a CallEnter node. - CallEnter Loc(CE, AMgr.getAnalysisContext(FD), Pred->getLocationContext()); - - ExplodedNode *N = Builder->generateNode(Loc, state, Pred); - Dst.Add(N); - return true; - } + if (!FD->hasBody(FD)) + return false; - // Check if we can find the function definition in other translation units. - if (AMgr.hasIndexer()) { - const AnalysisContext *C = AMgr.getAnalysisContextInAnotherTU(FD); - if (C == 0) - return false; + // Now we have the definition of the callee, create a CallEnter node. + CallEnter Loc(CE, FD, Pred->getLocationContext()); - CallEnter Loc(CE, C, Pred->getLocationContext()); - ExplodedNode *N = Builder->generateNode(Loc, state, Pred); + ExplodedNode *N = Builder->generateNode(Loc, state, Pred); + if (N) Dst.Add(N); - return true; - } - - return false; + return true; } void GRExprEngine::VisitCall(CallExpr* CE, ExplodedNode* Pred, diff --git a/tools/driver/Makefile b/tools/driver/Makefile index 260f53fec9e..b8c91e88738 100644 --- a/tools/driver/Makefile +++ b/tools/driver/Makefile @@ -28,8 +28,8 @@ include $(CLANG_LEVEL)/../../Makefile.config LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter codegen \ ipo selectiondag USEDLIBS = clangFrontend.a clangDriver.a clangCodeGen.a clangSema.a \ - clangChecker.a clangAnalysis.a clangIndex.a clangRewrite.a \ - clangAST.a clangParse.a clangLex.a clangBasic.a + clangChecker.a clangAnalysis.a clangRewrite.a clangAST.a \ + clangParse.a clangLex.a clangBasic.a include $(CLANG_LEVEL)/Makefile -- GitLab