Author: DonĂ¡t Nagy Date: 2026-04-07T13:47:17+02:00 New Revision: f40c234191802154d5b3fc3209908c3f2d6e1649
URL: https://github.com/llvm/llvm-project/commit/f40c234191802154d5b3fc3209908c3f2d6e1649 DIFF: https://github.com/llvm/llvm-project/commit/f40c234191802154d5b3fc3209908c3f2d6e1649.diff LOG: [NFC][analyzer] Spread use of 'Expr*' instead of 'Stmt*' (#188319) When I was browsing the codebase, I was surprised to see that the first parameter of `ProgramStateRef::BindExpr` was `const Stmt*` instead of `const Expr*`. As I surveyed calls to `BindExpr`, I realized that fortunately no code passes non-expression statements to `BindExpr` (anymore... it seems that earlier we had such hacks) so in this commit I'm able to change the type of the first parameter to `const Expr*`. There was a call to `BindExpr` where the first argument was the value of the data member `StackFrameContext::CallSite`, so I also changed the type of that member from `const Stmt*` to `const Expr*` because it was another statement pointer that always pointed to expressions (or null). This commit prepares the ground for using `Expr*` instead of `Stmt*` in `EnvironmentEntry`, which is currently a `pair<const Stmt *, const StackFrameContext *>` and will be updated in follow-up commits. This commit also includes minor unrelated simplifications and corrections. Added: Modified: clang/include/clang/Analysis/AnalysisDeclContext.h clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h clang/lib/Analysis/AnalysisDeclContext.cpp clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp clang/lib/StaticAnalyzer/Core/BugReporter.cpp clang/lib/StaticAnalyzer/Core/CallEvent.cpp clang/lib/StaticAnalyzer/Core/Environment.cpp clang/lib/StaticAnalyzer/Core/ExprEngine.cpp clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp clang/lib/StaticAnalyzer/Core/MemRegion.cpp clang/lib/StaticAnalyzer/Core/ProgramState.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Analysis/AnalysisDeclContext.h b/clang/include/clang/Analysis/AnalysisDeclContext.h index 2368b8ed911e7..00785d6d1db51 100644 --- a/clang/include/clang/Analysis/AnalysisDeclContext.h +++ b/clang/include/clang/Analysis/AnalysisDeclContext.h @@ -179,7 +179,7 @@ class AnalysisDeclContext { /// \copydoc LocationContextManager::getStackFrame() const StackFrameContext *getStackFrame(LocationContext const *ParentLC, - const Stmt *S, const CFGBlock *Blk, + const Expr *E, const CFGBlock *Blk, unsigned BlockCount, unsigned Index); /// \copydoc LocationContextManager::getBlockInvocationContext() @@ -300,7 +300,7 @@ class StackFrameContext : public LocationContext { friend class LocationContextManager; // The call site where this stack frame is established. - const Stmt *CallSite; + const Expr *CallSite; // The parent block of the call site. const CFGBlock *Block; @@ -314,15 +314,15 @@ class StackFrameContext : public LocationContext { const unsigned Index; StackFrameContext(AnalysisDeclContext *ADC, const LocationContext *ParentLC, - const Stmt *S, const CFGBlock *Block, unsigned BlockCount, + const Expr *E, const CFGBlock *Block, unsigned BlockCount, unsigned Index, int64_t ID) - : LocationContext(StackFrame, ADC, ParentLC, ID), CallSite(S), + : LocationContext(StackFrame, ADC, ParentLC, ID), CallSite(E), Block(Block), BlockCount(BlockCount), Index(Index) {} public: ~StackFrameContext() override = default; - const Stmt *getCallSite() const { return CallSite; } + const Expr *getCallSite() const { return CallSite; } const CFGBlock *getCallSiteBlock() const { return Block; } @@ -335,10 +335,10 @@ class StackFrameContext : public LocationContext { void Profile(llvm::FoldingSetNodeID &ID) override; static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ADC, - const LocationContext *ParentLC, const Stmt *S, + const LocationContext *ParentLC, const Expr *E, const CFGBlock *Block, unsigned BlockCount, unsigned Index) { - ProfileCommon(ID, StackFrame, ADC, ParentLC, S); + ProfileCommon(ID, StackFrame, ADC, ParentLC, E); ID.AddPointer(Block); ID.AddInteger(BlockCount); ID.AddInteger(Index); @@ -397,15 +397,16 @@ class LocationContextManager { /// /// \param ADC The AnalysisDeclContext. /// \param ParentLC The parent context of this newly created context. - /// \param S The call. + /// \param E The call expression. /// \param Block The basic block. - /// \param BlockCount The current count of entering into \p Blk. - /// \param Index The index of \p Blk. - /// \returns The context for \p D with parent context \p ParentLC. + /// \param BlockCount The current count of entering into \p Block. + /// \param StmtIdx The index of the call expression \p E among the + /// statements of the CFGBlock \p Block. + /// \returns The stack frame context corresponding to the call. const StackFrameContext *getStackFrame(AnalysisDeclContext *ADC, const LocationContext *ParentLC, - const Stmt *S, const CFGBlock *Block, - unsigned BlockCount, unsigned Index); + const Expr *E, const CFGBlock *Block, + unsigned BlockCount, unsigned StmtIdx); /// Obtain a context of the block invocation using its parent context. /// @@ -472,14 +473,6 @@ class AnalysisDeclContextManager { 0); } - /// \copydoc LocationContextManager::getStackFrame() - const StackFrameContext *getStackFrame(AnalysisDeclContext *ADC, - const LocationContext *Parent, - const Stmt *S, const CFGBlock *Block, - unsigned BlockCount, unsigned Index) { - return LocCtxMgr.getStackFrame(ADC, Parent, S, Block, BlockCount, Index); - } - BodyFarm &getBodyFarm(); /// Discard all previously created AnalysisDeclContexts. diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h index 66da79970ca19..0b9202bcf274e 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -259,7 +259,7 @@ class CallEvent { virtual RuntimeDefinition getRuntimeDefinition() const = 0; /// Returns the expression whose value will be the result of this call. - /// May be null. + /// Null if and only if 'this' is a CXXDestructorCall. virtual const Expr *getOriginExpr() const { return Origin.dyn_cast<const Expr *>(); } diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h index 498e36e1431fa..56453df79819e 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h @@ -32,6 +32,11 @@ class SymbolReaper; /// This allows the environment to manage context-sensitive bindings, /// which is essentially for modeling recursive function analysis, among /// other things. +/// FIXME: Use 'Expr' instead of 'Stmt' because associating a result with a +/// non-expression statement does not make sense. Currently the environment +/// only containts 'Expr's; and there is only one easy-to-eliminate hack in +/// 'processCallExit' and 'Environment::getSVal' that constructs and handles +/// 'EnvironmentEntry' instances with a 'ReturnStmt' as the 'first' part. class EnvironmentEntry : public std::pair<const Stmt *, const StackFrameContext *> { public: @@ -52,7 +57,7 @@ class EnvironmentEntry : public std::pair<const Stmt *, } }; -/// An immutable map from EnvironemntEntries to SVals. +/// An immutable map from EnvironmentEntries to SVals. class Environment { private: friend class EnvironmentManager; diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index d3dd6ca124b7f..942f5544c2b2e 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -278,9 +278,9 @@ class ProgramState : public llvm::FoldingSetNode { // Binding and retrieving values to/from the environment and symbolic store. //==---------------------------------------------------------------------==// - /// Create a new state by binding the value 'V' to the statement 'S' in the - /// state's environment. - [[nodiscard]] ProgramStateRef BindExpr(const Stmt *S, + /// Create a new state by binding the value \p V to the expression \p E in + /// the state's environment. + [[nodiscard]] ProgramStateRef BindExpr(const Expr *E, const LocationContext *LCtx, SVal V, bool Invalidate = true) const; diff --git a/clang/lib/Analysis/AnalysisDeclContext.cpp b/clang/lib/Analysis/AnalysisDeclContext.cpp index 6f153e7e65255..266d20632e3cc 100644 --- a/clang/lib/Analysis/AnalysisDeclContext.cpp +++ b/clang/lib/Analysis/AnalysisDeclContext.cpp @@ -312,9 +312,9 @@ BodyFarm &AnalysisDeclContextManager::getBodyFarm() { return FunctionBodyFarm; } const StackFrameContext * AnalysisDeclContext::getStackFrame(const LocationContext *ParentLC, - const Stmt *S, const CFGBlock *Blk, + const Expr *E, const CFGBlock *Blk, unsigned BlockCount, unsigned Index) { - return getLocationContextManager().getStackFrame(this, ParentLC, S, Blk, + return getLocationContextManager().getStackFrame(this, ParentLC, E, Blk, BlockCount, Index); } @@ -428,15 +428,16 @@ void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) { //===----------------------------------------------------------------------===// const StackFrameContext *LocationContextManager::getStackFrame( - AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s, - const CFGBlock *blk, unsigned blockCount, unsigned idx) { + AnalysisDeclContext *Ctx, const LocationContext *Parent, const Expr *E, + const CFGBlock *Blk, unsigned BlockCount, unsigned StmtIdx) { llvm::FoldingSetNodeID ID; - StackFrameContext::Profile(ID, ctx, parent, s, blk, blockCount, idx); + StackFrameContext::Profile(ID, Ctx, Parent, E, Blk, BlockCount, StmtIdx); void *InsertPos; auto *L = cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos)); if (!L) { - L = new StackFrameContext(ctx, parent, s, blk, blockCount, idx, ++NewID); + L = new StackFrameContext(Ctx, Parent, E, Blk, BlockCount, StmtIdx, + ++NewID); Contexts.InsertNode(L, InsertPos); } return L; @@ -514,9 +515,9 @@ void LocationContext::dumpStack(raw_ostream &Out) const { Out << "Calling " << AnalysisDeclContext::getFunctionName(D); else Out << "Calling anonymous code"; - if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) { + if (const Expr *E = cast<StackFrameContext>(LCtx)->getCallSite()) { Out << " at line "; - printLocation(Out, SM, S->getBeginLoc()); + printLocation(Out, SM, E->getBeginLoc()); } break; case Block: @@ -556,8 +557,8 @@ void LocationContext::printJson(raw_ostream &Out, const char *NL, Out << "anonymous code"; Out << "\", \"location\": "; - if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) { - printSourceLocationAsJson(Out, S->getBeginLoc(), SM); + if (const Expr *E = cast<StackFrameContext>(LCtx)->getCallSite()) { + printSourceLocationAsJson(Out, E->getBeginLoc(), SM); } else { Out << "null"; } diff --git a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp index 98b0fbeb72fbb..6d4389fda8753 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp @@ -172,7 +172,7 @@ void UninitializedObjectChecker::checkEndFunction( return; PathDiagnosticLocation LocUsedForUniqueing; - const Stmt *CallSite = Context.getStackFrame()->getCallSite(); + const Expr *CallSite = Context.getStackFrame()->getCallSite(); if (CallSite) LocUsedForUniqueing = PathDiagnosticLocation::createBegin( CallSite, Context.getSourceManager(), Node->getLocationContext()); diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp index 4c066520b668f..51039da20afba 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -323,7 +323,7 @@ std::string StackHintGeneratorForSymbol::getMessage(const ExplodedNode *N){ CallExitEnd CExit = P.castAs<CallExitEnd>(); // FIXME: Use CallEvent to abstract this over all calls. - const Stmt *CallSite = CExit.getCalleeContext()->getCallSite(); + const Expr *CallSite = CExit.getCalleeContext()->getCallSite(); const auto *CE = dyn_cast_or_null<CallExpr>(CallSite); if (!CE) return {}; diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp index e23f9fff4533a..eb32b9e581291 100644 --- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -186,7 +186,7 @@ CallEvent::getCalleeStackFrame(unsigned BlockCount) const { break; assert(Idx < Sz); - return ADC->getManager()->getStackFrame(ADC, LCtx, E, B, BlockCount, Idx); + return ADC->getStackFrame(LCtx, E, B, BlockCount, Idx); } const ParamVarRegion @@ -1480,7 +1480,7 @@ CallEventManager::getCaller(const StackFrameContext *CalleeCtx, CalleeCtx->getIndex()}; assert(CallerCtx && "This should not be used for top-level stack frames"); - const Stmt *CallSite = CalleeCtx->getCallSite(); + const Expr *CallSite = CalleeCtx->getCallSite(); if (CallSite) { if (CallEventRef<> Out = getCall(CallSite, State, CallerCtx, ElemRef)) @@ -1494,13 +1494,11 @@ CallEventManager::getCaller(const StackFrameContext *CalleeCtx, if (const auto *CE = dyn_cast<CXXConstructExpr>(CallSite)) return getCXXConstructorCall(CE, ThisVal.getAsRegion(), State, CallerCtx, ElemRef); - else if (const auto *CIE = dyn_cast<CXXInheritedCtorInitExpr>(CallSite)) + if (const auto *CIE = dyn_cast<CXXInheritedCtorInitExpr>(CallSite)) return getCXXInheritedConstructorCall(CIE, ThisVal.getAsRegion(), State, CallerCtx, ElemRef); - else { - // All other cases are handled by getCall. - llvm_unreachable("This is not an inlineable statement"); - } + // All other cases are handled by getCall. + llvm_unreachable("This is not an inlineable statement"); } // Fall back to the CFG. The only thing we haven't handled yet is diff --git a/clang/lib/StaticAnalyzer/Core/Environment.cpp b/clang/lib/StaticAnalyzer/Core/Environment.cpp index 5d9cbf681a5e9..bfe973afc3210 100644 --- a/clang/lib/StaticAnalyzer/Core/Environment.cpp +++ b/clang/lib/StaticAnalyzer/Core/Environment.cpp @@ -121,6 +121,11 @@ SVal Environment::getSVal(const EnvironmentEntry &Entry, return *svalBuilder.getConstantVal(cast<Expr>(S)); case Stmt::ReturnStmtClass: { + // FIXME: Move this logic to ExprEngine::processCallExit (the only location + // passes a ReturnStmt to this method) and then there will be no need to + // accept non-expression statements in getSVal (in fact, it will be + // possible to change the first member of EnvironmentEntry from const Stmt* + // to const Expr*). const auto *RS = cast<ReturnStmt>(S); if (const Expr *RE = RS->getRetValue()) return getSVal(EnvironmentEntry(RE, LCtx), svalBuilder); diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 4b24ac61337da..995a43c7e7aaf 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1885,7 +1885,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, // GNU __null is a pointer-width integer, not an actual pointer. ProgramStateRef state = Pred->getState(); state = state->BindExpr( - S, Pred->getLocationContext(), + cast<Expr>(S), Pred->getLocationContext(), svalBuilder.makeIntValWithWidth(getContext().VoidPtrTy, 0)); Bldr.generateNode(S, Pred, state); break; @@ -2017,7 +2017,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, const LocationContext *LCtx = Pred->getLocationContext(); for (const auto I : PreVisit) { ProgramStateRef State = I->getState(); - State = State->BindExpr(S, LCtx, *ConstantVal); + State = State->BindExpr(cast<Expr>(S), LCtx, *ConstantVal); if (IsTemporary) State = createTemporaryRegionIfNeeded(State, LCtx, cast<Expr>(S), @@ -2443,13 +2443,15 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, const auto *PE = cast<PseudoObjectExpr>(S); if (const Expr *Result = PE->getResultExpr()) { SVal V = state->getSVal(Result, Pred->getLocationContext()); - Bldr.generateNode(S, Pred, - state->BindExpr(S, Pred->getLocationContext(), V)); + Bldr.generateNode( + S, Pred, + state->BindExpr(cast<Expr>(S), Pred->getLocationContext(), V)); } else Bldr.generateNode(S, Pred, - state->BindExpr(S, Pred->getLocationContext(), - UnknownVal())); + state->BindExpr(cast<Expr>(S), + Pred->getLocationContext(), + UnknownVal())); Bldr.addNodes(Dst); break; @@ -2464,8 +2466,9 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, const auto *OIE = cast<ObjCIndirectCopyRestoreExpr>(S); const Expr *E = OIE->getSubExpr(); SVal V = state->getSVal(E, Pred->getLocationContext()); - Bldr.generateNode(S, Pred, - state->BindExpr(S, Pred->getLocationContext(), V)); + Bldr.generateNode( + S, Pred, + state->BindExpr(cast<Expr>(S), Pred->getLocationContext(), V)); Bldr.addNodes(Dst); break; } @@ -2478,7 +2481,7 @@ bool ExprEngine::replayWithoutInlining(ExplodedNode *N, const StackFrameContext *CallerSF = CalleeSF->getParent()->getStackFrame(); assert(CalleeSF && CallerSF); ExplodedNode *BeforeProcessingCall = nullptr; - const Stmt *CE = CalleeSF->getCallSite(); + const Expr *CE = CalleeSF->getCallSite(); // Find the first node before we started processing the call expression. while (N) { @@ -2515,9 +2518,16 @@ bool ExprEngine::replayWithoutInlining(ExplodedNode *N, BeforeProcessingCall->getLocationContext(), CE, nullptr, &PT); // Add the special flag to GDM to signal retrying with no inlining. // Note, changing the state ensures that we are not going to cache out. + // NOTE: This stores the call site (CE) in the state trait, but the the + // actual pointer value is only checked by an assertion; for the analysis, + // only the presence or absence of this trait matters. + // TODO: If we are handling a destructor call, CE is nullpointer (because it + // ultimately comes from the `Origin` of a `CXXDestructorCall`), which is + // indistinguishable from the absence (default state) of this state trait. + // I don't think that this bad logic causes actually observable problems, but + // it would be nice to clean it up if somebody has time to do so. ProgramStateRef NewNodeState = BeforeProcessingCall->getState(); - NewNodeState = - NewNodeState->set<ReplayWithoutInlining>(const_cast<Stmt *>(CE)); + NewNodeState = NewNodeState->set<ReplayWithoutInlining>(CE); // Make the new node a successor of BeforeProcessingCall. bool IsNew = false; diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index 701c7fdc88497..5807b4db61fef 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -231,7 +231,7 @@ SVal ExprEngine::computeObjectUnderConstruction( unsigned NVCaller = getNumVisited(CallerLCtx, SFC->getCallSiteBlock()); return computeObjectUnderConstruction( - cast<Expr>(SFC->getCallSite()), State, NVCaller, CallerLCtx, + SFC->getCallSite(), State, NVCaller, CallerLCtx, RTC->getConstructionContext(), CallOpts); } else { // We are on the top frame of the analysis. We do not know where is the @@ -454,8 +454,8 @@ ProgramStateRef ExprEngine::updateObjectsUnderConstruction( assert(!isa<BlockInvocationContext>(CallerLCtx)); } - return updateObjectsUnderConstruction(V, - cast<Expr>(SFC->getCallSite()), State, CallerLCtx, + return updateObjectsUnderConstruction( + V, SFC->getCallSite(), State, CallerLCtx, RTC->getConstructionContext(), CallOpts); } case ConstructionContext::ElidedTemporaryObjectKind: { diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index b4dc4fa8a077d..3dc3c9d05f24e 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -259,7 +259,7 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) { // look up the first enclosing stack frame. const StackFrameContext *CallerCtx = CalleeCtx->getParent()->getStackFrame(); - const Stmt *CE = CalleeCtx->getCallSite(); + const Expr *CE = CalleeCtx->getCallSite(); ProgramStateRef State = CEBNode->getState(); // Find the last statement in the function and the corresponding basic block. auto [LastSt, Blk] = getLastStmt(CEBNode); @@ -297,6 +297,10 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) { if (CE) { if (const ReturnStmt *RS = dyn_cast_or_null<ReturnStmt>(LastSt)) { const LocationContext *LCtx = CEBNode->getLocationContext(); + // FIXME: This tries to look up the return statement in the environment, + // which is special cased to look up the subexpression RS->getRetValue() + // in environment. Instead of relying on this hack, pass + // RS->getRetValue() to getSVal() after checking it for nullness. SVal V = State->getSVal(RS, LCtx); // Ensure that the return type matches the type of the returned Expr. @@ -304,10 +308,8 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) { QualType ReturnedTy = CallEvent::getDeclaredResultType(CalleeCtx->getDecl()); if (!ReturnedTy.isNull()) { - if (const Expr *Ex = dyn_cast<Expr>(CE)) { - V = adjustReturnValue(V, Ex->getType(), ReturnedTy, - getStoreManager()); - } + V = adjustReturnValue(V, CE->getType(), ReturnedTy, + getStoreManager()); } } @@ -587,7 +589,7 @@ void ExprEngine::inlineCall(WorkList *WList, const CallEvent &Call, } static ProgramStateRef getInlineFailedState(ProgramStateRef State, - const Stmt *CallE) { + const Expr *CallE) { const void *ReplayState = State->get<ReplayWithoutInlining>(); if (!ReplayState) return nullptr; @@ -1225,9 +1227,6 @@ void ExprEngine::defaultEvalCall(NodeBuilder &Bldr, ExplodedNode *Pred, return; } - // Try to inline the call. - // The origin expression here is just used as a kind of checksum; - // this should still be safe even for CallEvents that don't come from exprs. const Expr *E = Call.getOriginExpr(); ProgramStateRef InlinedFailedState = getInlineFailedState(State, E); diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp index f20e79ae675a4..5544d254929e5 100644 --- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -1044,21 +1044,26 @@ const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D, if (PVD) { unsigned Index = PVD->getFunctionScopeIndex(); const StackFrameContext *SFC = LC->getStackFrame(); - const Stmt *CallSite = SFC->getCallSite(); + const Expr *CallSite = SFC->getCallSite(); if (CallSite) { - const Decl *D = SFC->getDecl(); - if (const auto *FD = dyn_cast<FunctionDecl>(D)) { - if (Index < FD->param_size() && FD->parameters()[Index] == PVD) - return getSubRegion<ParamVarRegion>(cast<Expr>(CallSite), Index, - getStackArgumentsRegion(SFC)); - } else if (const auto *BD = dyn_cast<BlockDecl>(D)) { - if (Index < BD->param_size() && BD->parameters()[Index] == PVD) - return getSubRegion<ParamVarRegion>(cast<Expr>(CallSite), Index, - getStackArgumentsRegion(SFC)); - } else { - return getSubRegion<ParamVarRegion>(cast<Expr>(CallSite), Index, + const Decl *CalleeDecl = SFC->getDecl(); + bool ValidParam = true; + if (const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl)) { + ValidParam = + (Index < FD->param_size() && FD->getParamDecl(Index) == PVD); + } else if (const auto *BD = dyn_cast<BlockDecl>(CalleeDecl)) { + ValidParam = + (Index < BD->param_size() && BD->getParamDecl(Index) == PVD); + } + + if (ValidParam) { + return getSubRegion<ParamVarRegion>(CallSite, Index, getStackArgumentsRegion(SFC)); } + // FIXME: If ValidParam was false, this method would "fall through" and + // eventually return a NonParamVarRegion for this ParamVarDecl. That + // seems to be buggy, so I strongly suspect that ValidParam always ends + // up being true. } } diff --git a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp index 87485daa6e5c9..297719af34209 100644 --- a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp +++ b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -298,12 +298,11 @@ SVal ProgramState::getSVal(Loc location, QualType T) const { return V; } -ProgramStateRef ProgramState::BindExpr(const Stmt *S, - const LocationContext *LCtx, - SVal V, bool Invalidate) const{ - Environment NewEnv = - getStateManager().EnvMgr.bindExpr(Env, EnvironmentEntry(S, LCtx), V, - Invalidate); +ProgramStateRef ProgramState::BindExpr(const Expr *E, + const LocationContext *LCtx, SVal V, + bool Invalidate) const { + Environment NewEnv = getStateManager().EnvMgr.bindExpr( + Env, EnvironmentEntry(E, LCtx), V, Invalidate); if (NewEnv == Env) return this; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
