diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-07-26 19:03:47 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-07-26 19:04:23 +0000 |
| commit | 7fa27ce4a07f19b07799a767fc29416f3b625afb (patch) | |
| tree | 27825c83636c4de341eb09a74f49f5d38a15d165 /clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | |
| parent | e3b557809604d036af6e00c60f012c2025b59a5e (diff) | |
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/ExprEngine.cpp')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 67 |
1 files changed, 36 insertions, 31 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 977c2b7f51fd..144f034a9dfe 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -65,6 +65,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/ImmutableMap.h" #include "llvm/ADT/ImmutableSet.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Casting.h" @@ -386,15 +387,19 @@ ProgramStateRef ExprEngine::createTemporaryRegionIfNeeded( State = finishObjectConstruction(State, MT, LC); State = State->BindExpr(Result, LC, *V); return State; - } else { + } else if (const ValueDecl *VD = MT->getExtendingDecl()) { StorageDuration SD = MT->getStorageDuration(); + assert(SD != SD_FullExpression); // If this object is bound to a reference with static storage duration, we // put it in a different region to prevent "address leakage" warnings. if (SD == SD_Static || SD == SD_Thread) { - TR = MRMgr.getCXXStaticTempObjectRegion(Init); + TR = MRMgr.getCXXStaticLifetimeExtendedObjectRegion(Init, VD); } else { - TR = MRMgr.getCXXTempObjectRegion(Init, LC); + TR = MRMgr.getCXXLifetimeExtendedObjectRegion(Init, VD, LC); } + } else { + assert(MT->getStorageDuration() == SD_FullExpression); + TR = MRMgr.getCXXTempObjectRegion(Init, LC); } } else { TR = MRMgr.getCXXTempObjectRegion(Init, LC); @@ -1242,7 +1247,7 @@ ExprEngine::prepareStateForArrayDestruction(const ProgramStateRef State, const QualType &ElementTy, const LocationContext *LCtx, SVal *ElementCountVal) { - assert(Region != nullptr && "Not-null region expected"); + assert(Region != nullptr && "Not-null region expected"); QualType Ty = ElementTy.getDesugaredType(getContext()); while (const auto *NTy = dyn_cast<ArrayType>(Ty)) @@ -1313,7 +1318,8 @@ void ExprEngine::ProcessNewAllocator(const CXXNewExpr *NE, else { NodeBuilder Bldr(Pred, Dst, *currBldrCtx); const LocationContext *LCtx = Pred->getLocationContext(); - PostImplicitCall PP(NE->getOperatorNew(), NE->getBeginLoc(), LCtx); + PostImplicitCall PP(NE->getOperatorNew(), NE->getBeginLoc(), LCtx, + getCFGElementRef()); Bldr.generateNode(PP, Pred->getState(), Pred); } Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); @@ -1361,7 +1367,8 @@ void ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor, static SimpleProgramPointTag PT( "ExprEngine", "Skipping automatic 0 length array destruction, " "which shouldn't be in the CFG."); - PostImplicitCall PP(DtorDecl, varDecl->getLocation(), LCtx, &PT); + PostImplicitCall PP(DtorDecl, varDecl->getLocation(), LCtx, + getCFGElementRef(), &PT); NodeBuilder Bldr(Pred, Dst, *currBldrCtx); Bldr.generateSink(PP, Pred->getState(), Pred); return; @@ -1378,7 +1385,8 @@ void ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor, static SimpleProgramPointTag PT("ExprEngine", "Prepare for object destruction"); - PreImplicitCall PP(DtorDecl, varDecl->getLocation(), LCtx, &PT); + PreImplicitCall PP(DtorDecl, varDecl->getLocation(), LCtx, getCFGElementRef(), + &PT); Pred = Bldr.generateNode(PP, state, Pred); if (!Pred) @@ -1406,7 +1414,7 @@ void ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor, const CXXRecordDecl *RD = BTy->getAsCXXRecordDecl(); const CXXDestructorDecl *Dtor = RD->getDestructor(); - PostImplicitCall PP(Dtor, DE->getBeginLoc(), LCtx); + PostImplicitCall PP(Dtor, DE->getBeginLoc(), LCtx, getCFGElementRef()); NodeBuilder Bldr(Pred, Dst, *currBldrCtx); Bldr.generateNode(PP, Pred->getState(), Pred); return; @@ -1439,7 +1447,8 @@ void ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor, static SimpleProgramPointTag PT( "ExprEngine", "Skipping 0 length array delete destruction"); - PostImplicitCall PP(getDtorDecl(DTy), DE->getBeginLoc(), LCtx, &PT); + PostImplicitCall PP(getDtorDecl(DTy), DE->getBeginLoc(), LCtx, + getCFGElementRef(), &PT); NodeBuilder Bldr(Pred, Dst, *currBldrCtx); Bldr.generateNode(PP, Pred->getState(), Pred); return; @@ -1453,7 +1462,8 @@ void ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor, NodeBuilder Bldr(Pred, Dst, getBuilderContext()); static SimpleProgramPointTag PT("ExprEngine", "Prepare for object destruction"); - PreImplicitCall PP(getDtorDecl(DTy), DE->getBeginLoc(), LCtx, &PT); + PreImplicitCall PP(getDtorDecl(DTy), DE->getBeginLoc(), LCtx, + getCFGElementRef(), &PT); Pred = Bldr.generateNode(PP, State, Pred); if (!Pred) @@ -1513,7 +1523,8 @@ void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D, static SimpleProgramPointTag PT( "ExprEngine", "Skipping member 0 length array destruction, which " "shouldn't be in the CFG."); - PostImplicitCall PP(DtorDecl, Member->getLocation(), LCtx, &PT); + PostImplicitCall PP(DtorDecl, Member->getLocation(), LCtx, + getCFGElementRef(), &PT); NodeBuilder Bldr(Pred, Dst, *currBldrCtx); Bldr.generateSink(PP, Pred->getState(), Pred); return; @@ -1529,7 +1540,8 @@ void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D, static SimpleProgramPointTag PT("ExprEngine", "Prepare for object destruction"); - PreImplicitCall PP(DtorDecl, Member->getLocation(), LCtx, &PT); + PreImplicitCall PP(DtorDecl, Member->getLocation(), LCtx, getCFGElementRef(), + &PT); Pred = Bldr.generateNode(PP, State, Pred); if (!Pred) @@ -1565,7 +1577,7 @@ void ExprEngine::ProcessTemporaryDtor(const CFGTemporaryDtor D, NodeBuilder Bldr(Pred, Dst, *currBldrCtx); PostImplicitCall PP(D.getDestructorDecl(getContext()), D.getBindTemporaryExpr()->getBeginLoc(), - Pred->getLocationContext()); + Pred->getLocationContext(), getCFGElementRef()); Bldr.generateNode(PP, State, Pred); return; } @@ -2114,7 +2126,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, } } } - // FALLTHROUGH [[fallthrough]]; } @@ -2630,9 +2641,7 @@ static const Stmt *ResolveCondition(const Stmt *Condition, // The invariants are still shifting, but it is possible that the // last element in a CFGBlock is not a CFGStmt. Look for the last // CFGStmt as the value of the condition. - CFGBlock::const_reverse_iterator I = B->rbegin(), E = B->rend(); - for (; I != E; ++I) { - CFGElement Elem = *I; + for (CFGElement Elem : llvm::reverse(*B)) { std::optional<CFGStmt> CS = Elem.getAs<CFGStmt>(); if (!CS) continue; @@ -2840,9 +2849,9 @@ void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) { if (std::optional<loc::GotoLabel> LV = V.getAs<loc::GotoLabel>()) { const LabelDecl *L = LV->getLabel(); - for (iterator I = builder.begin(), E = builder.end(); I != E; ++I) { - if (I.getLabel() == L) { - builder.generateNode(I, state); + for (iterator Succ : builder) { + if (Succ.getLabel() == L) { + builder.generateNode(Succ, state); return; } } @@ -2861,8 +2870,8 @@ void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) { // This is really a catch-all. We don't support symbolics yet. // FIXME: Implement dispatch for symbolic pointers. - for (iterator I = builder.begin(), E = builder.end(); I != E; ++I) - builder.generateNode(I, state); + for (iterator Succ : builder) + builder.generateNode(Succ, state); } void ExprEngine::processBeginOfFunction(NodeBuilderContext &BC, @@ -3795,12 +3804,9 @@ struct DOTGraphTraits<ExplodedGraph*> : public DefaultDOTGraphTraits { BugReporter &BR = static_cast<ExprEngine &>( N->getState()->getStateManager().getOwningEngine()).getBugReporter(); - const auto EQClasses = - llvm::make_range(BR.EQClasses_begin(), BR.EQClasses_end()); - - for (const auto &EQ : EQClasses) { - for (const auto &I : EQ.getReports()) { - const auto *PR = dyn_cast<PathSensitiveBugReport>(I.get()); + for (const auto &Class : BR.equivalenceClasses()) { + for (const auto &Report : Class.getReports()) { + const auto *PR = dyn_cast<PathSensitiveBugReport>(Report.get()); if (!PR) continue; const ExplodedNode *EN = PR->getErrorNode(); @@ -3898,10 +3904,9 @@ std::string ExprEngine::DumpGraph(bool trim, StringRef Filename) { std::vector<const ExplodedNode *> Src; // Iterate through the reports and get their nodes. - for (BugReporter::EQClasses_iterator - EI = BR.EQClasses_begin(), EE = BR.EQClasses_end(); EI != EE; ++EI) { + for (const auto &Class : BR.equivalenceClasses()) { const auto *R = - dyn_cast<PathSensitiveBugReport>(EI->getReports()[0].get()); + dyn_cast<PathSensitiveBugReport>(Class.getReports()[0].get()); if (!R) continue; const auto *N = const_cast<ExplodedNode *>(R->getErrorNode()); |
