[clang] [analyzer][NFC] Move PrettyStackTraceLocationContext into dispatchWorkItem (PR #140035)
Balázs Benics via cfe-commits
cfe-commits at lists.llvm.org
Thu May 15 03:42:57 PDT 2025
https://github.com/balazs-benics-sonarsource updated https://github.com/llvm/llvm-project/pull/140035
>From 42343959f623153dc9421e3bb569b2f0527ec119 Mon Sep 17 00:00:00 2001
From: Balazs Benics <balazs.benics at sonarsource.com>
Date: Thu, 15 May 2025 11:17:24 +0200
Subject: [PATCH 1/2] [analyzer][NFC] Move PrettyStackTraceLocationContext into
dispatchWorkItem
---
clang/lib/StaticAnalyzer/Core/CoreEngine.cpp | 2 ++
clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 17 +++--------------
.../Core/ExprEngineCallAndReturn.cpp | 5 +----
3 files changed, 6 insertions(+), 18 deletions(-)
diff --git a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
index 2e6631f2f620c..8cc086a12ad70 100644
--- a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
+#include "PrettyStackTraceLocationContext.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/Stmt.h"
@@ -216,6 +217,7 @@ void CoreEngine::dispatchWorkItem(ExplodedNode *Pred, ProgramPoint Loc,
llvm::TimeTraceScope tcs{timeTraceScopeName(Loc), [Loc, Pred]() {
return timeTraceMetadata(Pred, Loc);
}};
+ PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext());
// Dispatch on the location type.
switch (Loc.getKind()) {
case ProgramPoint::BlockEdgeKind:
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index ebad83dad0c8f..1afd4b52eb354 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -968,7 +968,6 @@ void ExprEngine::processEndWorklist() {
void ExprEngine::processCFGElement(const CFGElement E, ExplodedNode *Pred,
unsigned StmtIdx, NodeBuilderContext *Ctx) {
- PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext());
currStmtIdx = StmtIdx;
currBldrCtx = Ctx;
@@ -2541,7 +2540,6 @@ static const LocationContext *getInlinedLocationContext(ExplodedNode *Node,
void ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
NodeBuilderWithSinks &nodeBuilder,
ExplodedNode *Pred) {
- PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext());
// If we reach a loop which has a known bound (and meets
// other constraints) then consider completely unrolling it.
if(AMgr.options.ShouldUnrollLoops) {
@@ -2808,8 +2806,6 @@ void ExprEngine::processBranch(
std::optional<unsigned> IterationsCompletedInLoop) {
assert((!Condition || !isa<CXXBindTemporaryExpr>(Condition)) &&
"CXXBindTemporaryExprs are handled by processBindTemporary.");
- const LocationContext *LCtx = Pred->getLocationContext();
- PrettyStackTraceLocationContext StackCrashInfo(LCtx);
currBldrCtx = &BldCtx;
// Check for NULL conditions; e.g. "for(;;)"
@@ -2935,13 +2931,9 @@ void ExprEngine::processBranch(
REGISTER_TRAIT_WITH_PROGRAMSTATE(InitializedGlobalsSet,
llvm::ImmutableSet<const VarDecl *>)
-void ExprEngine::processStaticInitializer(const DeclStmt *DS,
- NodeBuilderContext &BuilderCtx,
- ExplodedNode *Pred,
- ExplodedNodeSet &Dst,
- const CFGBlock *DstT,
- const CFGBlock *DstF) {
- PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext());
+void ExprEngine::processStaticInitializer(
+ const DeclStmt *DS, NodeBuilderContext &BuilderCtx, ExplodedNode *Pred,
+ ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF) {
currBldrCtx = &BuilderCtx;
const auto *VD = cast<VarDecl>(DS->getSingleDecl());
@@ -3064,9 +3056,6 @@ void ExprEngine::processEndOfFunction(NodeBuilderContext& BC,
assert(areAllObjectsFullyConstructed(Pred->getState(),
Pred->getLocationContext(),
Pred->getStackFrame()->getParent()));
-
- PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext());
-
ExplodedNodeSet Dst;
if (Pred->getLocationContext()->inTopFrame()) {
// Remove dead symbols.
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index 90625a96e9059..63bdc58030187 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -44,8 +44,6 @@ STAT_COUNTER(NumReachedInlineCountMax,
void ExprEngine::processCallEnter(NodeBuilderContext& BC, CallEnter CE,
ExplodedNode *Pred) {
// Get the entry block in the CFG of the callee.
- const StackFrameContext *calleeCtx = CE.getCalleeContext();
- PrettyStackTraceLocationContext CrashInfo(calleeCtx);
const CFGBlock *Entry = CE.getEntry();
// Validate the CFG.
@@ -56,7 +54,7 @@ void ExprEngine::processCallEnter(NodeBuilderContext& BC, CallEnter CE,
const CFGBlock *Succ = *(Entry->succ_begin());
// Construct an edge representing the starting location in the callee.
- BlockEdge Loc(Entry, Succ, calleeCtx);
+ BlockEdge Loc(Entry, Succ, CE.getCalleeContext());
ProgramStateRef state = Pred->getState();
@@ -253,7 +251,6 @@ ProgramStateRef ExprEngine::removeStateTraitsUsedForArrayEvaluation(
/// 5. PostStmt<CallExpr>
void ExprEngine::processCallExit(ExplodedNode *CEBNode) {
// Step 1 CEBNode was generated before the call.
- PrettyStackTraceLocationContext CrashInfo(CEBNode->getLocationContext());
const StackFrameContext *calleeCtx = CEBNode->getStackFrame();
// The parent context might not be a stack frame, so make sure we
>From 3451e53aa0301bf3051167003dffc97936390536 Mon Sep 17 00:00:00 2001
From: Balazs Benics <balazs.benics at sonarsource.com>
Date: Thu, 15 May 2025 12:42:32 +0200
Subject: [PATCH 2/2] Drop unused include
---
.../Core/ExprEngineCallAndReturn.cpp | 28 ++++++++++++++-----
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index 63bdc58030187..75aca0bac9e0e 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -10,7 +10,6 @@
//
//===----------------------------------------------------------------------===//
-#include "PrettyStackTraceLocationContext.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
@@ -41,6 +40,11 @@ STAT_COUNTER(NumInlinedCalls, "The # of times we inlined a call");
STAT_COUNTER(NumReachedInlineCountMax,
"The # of times we reached inline count maximum");
+STAT_COUNTER(NumDefaultCallEvals, "The # of times default call eval used.");
+
+STAT_COUNTER(NumDefaultConservativeCallEvals,
+ "The # of times default conservative call eval used.");
+
void ExprEngine::processCallEnter(NodeBuilderContext& BC, CallEnter CE,
ExplodedNode *Pred) {
// Get the entry block in the CFG of the callee.
@@ -574,7 +578,8 @@ void ExprEngine::inlineCall(WorkList *WList, const CallEvent &Call,
Bldr.takeNodes(Pred);
NumInlinedCalls++;
- Engine.FunctionSummaries->bumpNumTimesInlined(D);
+ Engine.FunctionSummaries->bumpNumTimesCalleeInlined(
+ BR.getAnalysisEntryPoint(), D);
// Do not mark as visited in the 2nd run (CTUWList), so the function will
// be visited as top-level, this way we won't loose reports in non-ctu
@@ -743,7 +748,6 @@ ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call,
const LocationContext *LCtx,
ProgramStateRef State) {
const Expr *E = Call.getOriginExpr();
- const ConstCFGElementRef &Elem = Call.getCFGElementRef();
if (!E)
return State;
@@ -786,7 +790,7 @@ ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call,
RegionAndSymbolInvalidationTraits ITraits;
ITraits.setTrait(TargetR,
RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion);
- State = State->invalidateRegions(TargetR, Elem, Count, LCtx,
+ State = State->invalidateRegions(TargetR, E, Count, LCtx,
/* CausesPointerEscape=*/false, nullptr,
&Call, &ITraits);
@@ -798,7 +802,7 @@ ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call,
// a regular unknown pointer.
const auto *CNE = dyn_cast<CXXNewExpr>(E);
if (CNE && CNE->getOperatorNew()->isReplaceableGlobalAllocationFunction()) {
- R = svalBuilder.getConjuredHeapSymbolVal(Elem, LCtx, E->getType(), Count);
+ R = svalBuilder.getConjuredHeapSymbolVal(E, LCtx, Count);
const MemRegion *MR = R.getAsRegion()->StripCasts();
// Store the extent of the allocated object(s).
@@ -820,9 +824,10 @@ ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call,
if (Size.isUndef())
Size = UnknownVal();
- State = setDynamicExtent(State, MR, Size.castAs<DefinedOrUnknownSVal>());
+ State = setDynamicExtent(State, MR, Size.castAs<DefinedOrUnknownSVal>(),
+ svalBuilder);
} else {
- R = svalBuilder.conjureSymbolVal(Elem, LCtx, ResultTy, Count);
+ R = svalBuilder.conjureSymbolVal(nullptr, E, LCtx, ResultTy, Count);
}
}
return State->BindExpr(E, LCtx, R);
@@ -832,6 +837,7 @@ ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call,
// a conjured return value.
void ExprEngine::conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr,
ExplodedNode *Pred, ProgramStateRef State) {
+ ++NumDefaultConservativeCallEvals;
State = Call.invalidateRegions(currBldrCtx->blockCount(), State);
State = bindReturnValue(Call, Pred->getLocationContext(), State);
@@ -1015,6 +1021,13 @@ static bool isCXXSharedPtrDtor(const FunctionDecl *FD) {
/// CFG, to determine whether the analyzer should ever consider inlining it,
/// in any context.
bool ExprEngine::mayInlineDecl(AnalysisDeclContext *CalleeADC) const {
+
+ if (CalleeADC->getDecl()->isInvalidDecl() ||
+ llvm::any_of(
+ CalleeADC->getDecl()->specific_attrs<AnnotateAttr>(),
+ [](auto A) { return A->getAnnotation() == "hasParsingErrors"; }))
+ return false;
+
AnalyzerOptions &Opts = AMgr.getAnalyzerOptions();
// FIXME: Do not inline variadic calls.
if (CallEvent::isVariadic(CalleeADC->getDecl()))
@@ -1216,6 +1229,7 @@ static bool isTrivialObjectAssignment(const CallEvent &Call) {
void ExprEngine::defaultEvalCall(NodeBuilder &Bldr, ExplodedNode *Pred,
const CallEvent &CallTemplate,
const EvalCallOptions &CallOpts) {
+ ++NumDefaultCallEvals;
// Make sure we have the most recent state attached to the call.
ProgramStateRef State = Pred->getState();
CallEventRef<> Call = CallTemplate.cloneWithState(State);
More information about the cfe-commits
mailing list