diff options
author | Rui Ueyama <ruiu@google.com> | 2014-08-06 22:01:54 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2014-08-06 22:01:54 +0000 |
commit | a89f9c8fdb77aefeaebd4d0bf956e09927f89f08 (patch) | |
tree | 9da1a8328739c13786e2aab9d5a8abcafdf749c7 /clang/lib/StaticAnalyzer/Core | |
parent | 3d7162b1cc33f1126ab3c05ebfea19ffed82c699 (diff) | |
download | bcm5719-llvm-a89f9c8fdb77aefeaebd4d0bf956e09927f89f08.tar.gz bcm5719-llvm-a89f9c8fdb77aefeaebd4d0bf956e09927f89f08.zip |
Revert "Fix modelling of non-lifetime-extended temporary destructors in the analyzer."
This reverts commit r214962 because after the change the
following code doesn't compile with -Wreturn-type -Werror.
#include <cstdlib>
class NoReturn {
public:
~NoReturn() __attribute__((noreturn)) { exit(1); }
};
int check() {
true ? NoReturn() : NoReturn();
}
llvm-svn: 214998
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/CoreEngine.cpp | 17 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 103 |
2 files changed, 10 insertions, 110 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp index 2a7c8e170d8..4623c358a9e 100644 --- a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -14,7 +14,6 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h" #include "clang/AST/Expr.h" -#include "clang/AST/ExprCXX.h" #include "clang/AST/StmtCXX.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" @@ -347,11 +346,6 @@ void CoreEngine::HandleBlockExit(const CFGBlock * B, ExplodedNode *Pred) { default: llvm_unreachable("Analysis for this terminator not implemented."); - case Stmt::CXXBindTemporaryExprClass: - HandleCleanupTemporaryBranch( - cast<CXXBindTemporaryExpr>(B->getTerminator().getStmt()), B, Pred); - return; - // Model static initializers. case Stmt::DeclStmtClass: HandleStaticInit(cast<DeclStmt>(Term), B, Pred); @@ -467,17 +461,6 @@ void CoreEngine::HandleBranch(const Stmt *Cond, const Stmt *Term, enqueue(Dst); } -void CoreEngine::HandleCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE, - const CFGBlock *B, - ExplodedNode *Pred) { - assert(B->succ_size() == 2); - NodeBuilderContext Ctx(*this, B, Pred); - ExplodedNodeSet Dst; - SubEng.processCleanupTemporaryBranch(BTE, Ctx, Pred, Dst, *(B->succ_begin()), - *(B->succ_begin() + 1)); - // Enqueue the new frontier onto the worklist. - enqueue(Dst); -} void CoreEngine::HandleStaticInit(const DeclStmt *DS, const CFGBlock *B, ExplodedNode *Pred) { diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index b30a4417e9a..f4636ef18aa 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -51,15 +51,6 @@ STATISTIC(NumMaxBlockCountReachedInInlined, STATISTIC(NumTimesRetriedWithoutInlining, "The # of times we re-evaluated a call without inlining"); -typedef std::pair<const CXXBindTemporaryExpr *, const StackFrameContext *> - CXXBindTemporaryContext; - -// Keeps track of whether CXXBindTemporaryExpr nodes have been evaluated. -// The StackFrameContext assures that nested calls due to inlined recursive -// functions do not interfere. -REGISTER_TRAIT_WITH_PROGRAMSTATE(InitializedTemporariesSet, - llvm::ImmutableSet<CXXBindTemporaryContext>) - //===----------------------------------------------------------------------===// // Engine construction and deletion. //===----------------------------------------------------------------------===// @@ -668,59 +659,13 @@ void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D, void ExprEngine::ProcessTemporaryDtor(const CFGTemporaryDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst) { - ExplodedNodeSet CleanDtorState; - StmtNodeBuilder StmtBldr(Pred, CleanDtorState, *currBldrCtx); - ProgramStateRef State = Pred->getState(); - assert(State->contains<InitializedTemporariesSet>( - std::make_pair(D.getBindTemporaryExpr(), Pred->getStackFrame()))); - State = State->remove<InitializedTemporariesSet>( - std::make_pair(D.getBindTemporaryExpr(), Pred->getStackFrame())); - StmtBldr.generateNode(D.getBindTemporaryExpr(), Pred, State); QualType varType = D.getBindTemporaryExpr()->getSubExpr()->getType(); - assert(CleanDtorState.size() == 1); - ExplodedNode *CleanPred = *CleanDtorState.begin(); - // FIXME: Inlining of temporary destructors is not supported yet anyway, so - // we just put a NULL region for now. This will need to be changed later. - VisitCXXDestructor(varType, nullptr, D.getBindTemporaryExpr(), - /*IsBase=*/false, CleanPred, Dst); -} - -void ExprEngine::processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE, - NodeBuilderContext &BldCtx, - ExplodedNode *Pred, - ExplodedNodeSet &Dst, - const CFGBlock *DstT, - const CFGBlock *DstF) { - BranchNodeBuilder TempDtorBuilder(Pred, Dst, BldCtx, DstT, DstF); - if (Pred->getState()->contains<InitializedTemporariesSet>( - std::make_pair(BTE, Pred->getStackFrame()))) { - TempDtorBuilder.markInfeasible(false); - TempDtorBuilder.generateNode(Pred->getState(), true, Pred); - } else { - TempDtorBuilder.markInfeasible(true); - TempDtorBuilder.generateNode(Pred->getState(), false, Pred); - } -} -void ExprEngine::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE, - ExplodedNodeSet &PreVisit, - ExplodedNodeSet &Dst) { - if (!getAnalysisManager().options.includeTemporaryDtorsInCFG()) { - // In case we don't have temporary destructors in the CFG, do not mark - // the initialization - we would otherwise never clean it up. - Dst = PreVisit; - return; - } - StmtNodeBuilder StmtBldr(PreVisit, Dst, *currBldrCtx); - for (ExplodedNode *Node : PreVisit) { - ProgramStateRef State = Node->getState(); - assert(!State->contains<InitializedTemporariesSet>( - std::make_pair(BTE, Node->getStackFrame()))); - State = State->add<InitializedTemporariesSet>( - std::make_pair(BTE, Node->getStackFrame())); - StmtBldr.generateNode(BTE, Node, State); - } + // FIXME: Inlining of temporary destructors is not supported yet anyway, so we + // just put a NULL region for now. This will need to be changed later. + VisitCXXDestructor(varType, nullptr, D.getBindTemporaryExpr(), + /*IsBase=*/ false, Pred, Dst); } void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, @@ -828,17 +773,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, // Handled due to fully linearised CFG. break; - case Stmt::CXXBindTemporaryExprClass: { - Bldr.takeNodes(Pred); - ExplodedNodeSet PreVisit; - getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); - ExplodedNodeSet Next; - VisitCXXBindTemporaryExpr(cast<CXXBindTemporaryExpr>(S), PreVisit, Next); - getCheckerManager().runCheckersForPostStmt(Dst, Next, S, *this); - Bldr.addNodes(Dst); - break; - } - // Cases not handled yet; but will handle some day. case Stmt::DesignatedInitExprClass: case Stmt::ExtVectorElementExprClass: @@ -876,6 +810,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::SizeOfPackExprClass: case Stmt::StringLiteralClass: case Stmt::ObjCStringLiteralClass: + case Stmt::CXXBindTemporaryExprClass: case Stmt::CXXPseudoDestructorExprClass: case Stmt::SubstNonTypeTemplateParmExprClass: case Stmt::CXXNullPtrLiteralExprClass: { @@ -1470,8 +1405,11 @@ static const Stmt *ResolveCondition(const Stmt *Condition, if (!BO || !BO->isLogicalOp()) return Condition; - assert(!B->getTerminator().isTemporaryDtorsBranch() && - "Temporary destructor branches handled by processBindTemporary."); + // FIXME: This is a workaround until we handle temporary destructor branches + // correctly; currently, temporary destructor branches lead to blocks that + // only have a terminator (and no statements). These blocks violate the + // invariant this function assumes. + if (B->getTerminator().isTemporaryDtorsBranch()) return Condition; // For logical operations, we still have the case where some branches // use the traditional "merge" approach and others sink the branch @@ -1500,8 +1438,6 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF) { - assert((!Condition || !isa<CXXBindTemporaryExpr>(Condition)) && - "CXXBindTemporaryExprs are handled by processBindTemporary."); const LocationContext *LCtx = Pred->getLocationContext(); PrettyStackTraceLocationContext StackCrashInfo(LCtx); currBldrCtx = &BldCtx; @@ -1665,29 +1601,10 @@ void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) { builder.generateNode(I, state); } -#if 0 -static bool stackFrameDoesNotContainInitializedTemporaries(ExplodedNode &Pred) { - const StackFrameContext* Frame = Pred.getStackFrame(); - const llvm::ImmutableSet<CXXBindTemporaryContext> &Set = - Pred.getState()->get<InitializedTemporariesSet>(); - return std::find_if(Set.begin(), Set.end(), - [&](const CXXBindTemporaryContext &Ctx) { - if (Ctx.second == Frame) { - Ctx.first->dump(); - llvm::errs() << "\n"; - } - return Ctx.second == Frame; - }) == Set.end(); -} -#endif - /// ProcessEndPath - Called by CoreEngine. Used to generate end-of-path /// nodes when the control reaches the end of a function. void ExprEngine::processEndOfFunction(NodeBuilderContext& BC, ExplodedNode *Pred) { - // FIXME: Assert that stackFrameDoesNotContainInitializedTemporaries(*Pred)). - // We currently cannot enable this assert, as lifetime extended temporaries - // are not modelled correctly. PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext()); StateMgr.EndPath(Pred->getState()); |