https://github.com/balazs-benics-sonarsource created https://github.com/llvm/llvm-project/pull/140861
This helps to gain contextual information about how we entered a CFG block. The `noexprcrash.c` test probably changed due to the fact that now BlockEntrance ProgramPoint Profile also hashes the pointer of the previous CFG block. I didn't investigate. CPP-6483 From 1378271ee639bf3307cb373f07f730978373be7b Mon Sep 17 00:00:00 2001 From: Balazs Benics <balazs.ben...@sonarsource.com> Date: Thu, 15 May 2025 15:21:48 +0200 Subject: [PATCH] [analyzer] Add previous CFG block to BlockEntrance ProgramPoints This helps to gain contextual information about how we entered a CFG block. The `noexprcrash.c` test probably changed due to the fact that now BlockEntrance ProgramPoint Profile also hashes the pointer of the previous CFG block. I didn't investigate. CPP-6483 --- clang/include/clang/Analysis/ProgramPoint.h | 18 ++++++++++++------ clang/lib/StaticAnalyzer/Core/CoreEngine.cpp | 2 +- .../Analysis/exploration_order/noexprcrash.c | 11 ++++++----- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/clang/include/clang/Analysis/ProgramPoint.h b/clang/include/clang/Analysis/ProgramPoint.h index c40aa3d8ffb72..096ad48a42984 100644 --- a/clang/include/clang/Analysis/ProgramPoint.h +++ b/clang/include/clang/Analysis/ProgramPoint.h @@ -224,10 +224,14 @@ class ProgramPoint { class BlockEntrance : public ProgramPoint { public: - BlockEntrance(const CFGBlock *B, const LocationContext *L, - const ProgramPointTag *tag = nullptr) - : ProgramPoint(B, BlockEntranceKind, L, tag) { - assert(B && "BlockEntrance requires non-null block"); + BlockEntrance(const CFGBlock *PrevBlock, const CFGBlock *CurrBlock, + const LocationContext *L, const ProgramPointTag *Tag = nullptr) + : ProgramPoint(CurrBlock, PrevBlock, BlockEntranceKind, L, Tag) { + assert(CurrBlock && "BlockEntrance requires non-null block"); + } + + const CFGBlock *getPreviousBlock() const { + return reinterpret_cast<const CFGBlock *>(getData2()); } const CFGBlock *getBlock() const { @@ -760,13 +764,15 @@ template <> struct DenseMapInfo<clang::ProgramPoint> { static inline clang::ProgramPoint getEmptyKey() { uintptr_t x = reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7; - return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), nullptr); + return clang::BlockEntrance(nullptr, reinterpret_cast<clang::CFGBlock *>(x), + nullptr); } static inline clang::ProgramPoint getTombstoneKey() { uintptr_t x = reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7; - return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), nullptr); + return clang::BlockEntrance(nullptr, reinterpret_cast<clang::CFGBlock *>(x), + nullptr); } static unsigned getHashValue(const clang::ProgramPoint &Loc) { diff --git a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp index 8cc086a12ad70..bedb11f8b94a5 100644 --- a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -315,7 +315,7 @@ void CoreEngine::HandleBlockEdge(const BlockEdge &L, ExplodedNode *Pred) { // Call into the ExprEngine to process entering the CFGBlock. ExplodedNodeSet dstNodes; - BlockEntrance BE(Blk, Pred->getLocationContext()); + BlockEntrance BE(L.getSrc(), L.getDst(), Pred->getLocationContext()); NodeBuilderWithSinks nodeBuilder(Pred, dstNodes, BuilderCtx, BE); ExprEng.processCFGBlockEntrance(L, nodeBuilder, Pred); diff --git a/clang/test/Analysis/exploration_order/noexprcrash.c b/clang/test/Analysis/exploration_order/noexprcrash.c index 75c2f0e6798a3..427c669783374 100644 --- a/clang/test/Analysis/exploration_order/noexprcrash.c +++ b/clang/test/Analysis/exploration_order/noexprcrash.c @@ -1,17 +1,18 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -analyzer-config exploration_strategy=unexplored_first %s -// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -analyzer-config exploration_strategy=dfs %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify=common,ufirst -analyzer-config exploration_strategy=unexplored_first %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify=common,dfs -analyzer-config exploration_strategy=dfs %s extern void clang_analyzer_eval(int); typedef struct { char a; } b; int c(b* input) { - int x = (input->a ?: input) ? 1 : 0; // expected-warning{{pointer/integer type mismatch}} + int x = (input->a ?: input) ? 1 : 0; // common-warning{{pointer/integer type mismatch}} if (input->a) { // FIXME: The value should actually be "TRUE", // but is incorrect due to a bug. - clang_analyzer_eval(x); // expected-warning{{FALSE}} + // dfs-warning@+1 {{FALSE}} ufirst-warning@+1 {{TRUE}} + clang_analyzer_eval(x); } else { - clang_analyzer_eval(x); // expected-warning{{TRUE}} + clang_analyzer_eval(x); // common-warning{{TRUE}} } return x; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits