[clang] [analyzer] Add previous CFG block to BlockEntrance ProgramPoints (PR #140861)
https://github.com/balazs-benics-sonarsource closed https://github.com/llvm/llvm-project/pull/140861 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Add previous CFG block to BlockEntrance ProgramPoints (PR #140861)
https://github.com/NagyDonat commented: LGTM, straightforward simple extension. https://github.com/llvm/llvm-project/pull/140861 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Add previous CFG block to BlockEntrance ProgramPoints (PR #140861)
https://github.com/NagyDonat approved this pull request. https://github.com/llvm/llvm-project/pull/140861 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Add previous CFG block to BlockEntrance ProgramPoints (PR #140861)
llvmbot wrote: @llvm/pr-subscribers-clang-static-analyzer-1 Author: Balázs Benics (balazs-benics-sonarsource) Changes 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 --- Full diff: https://github.com/llvm/llvm-project/pull/140861.diff 3 Files Affected: - (modified) clang/include/clang/Analysis/ProgramPoint.h (+12-6) - (modified) clang/lib/StaticAnalyzer/Core/CoreEngine.cpp (+1-1) - (modified) clang/test/Analysis/exploration_order/noexprcrash.c (+6-5) ``diff 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(getData2()); } const CFGBlock *getBlock() const { @@ -760,13 +764,15 @@ template <> struct DenseMapInfo { static inline clang::ProgramPoint getEmptyKey() { uintptr_t x = reinterpret_cast(DenseMapInfo::getEmptyKey()) & ~0x7; - return clang::BlockEntrance(reinterpret_cast(x), nullptr); + return clang::BlockEntrance(nullptr, reinterpret_cast(x), + nullptr); } static inline clang::ProgramPoint getTombstoneKey() { uintptr_t x = reinterpret_cast(DenseMapInfo::getTombstoneKey()) & ~0x7; - return clang::BlockEntrance(reinterpret_cast(x), nullptr); + return clang::BlockEntrance(nullptr, reinterpret_cast(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; } `` https://github.com/llvm/llvm-project/pull/140861 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Add previous CFG block to BlockEntrance ProgramPoints (PR #140861)
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 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(getData2()); } const CFGBlock *getBlock() const { @@ -760,13 +764,15 @@ template <> struct DenseMapInfo { static inline clang::ProgramPoint getEmptyKey() { uintptr_t x = reinterpret_cast(DenseMapInfo::getEmptyKey()) & ~0x7; - return clang::BlockEntrance(reinterpret_cast(x), nullptr); + return clang::BlockEntrance(nullptr, reinterpret_cast(x), + nullptr); } static inline clang::ProgramPoint getTombstoneKey() { uintptr_t x = reinterpret_cast(DenseMapInfo::getTombstoneKey()) & ~0x7; - return clang::BlockEntrance(reinterpret_cast(x), nullptr); + return clang::BlockEntrance(nullptr, reinterpret_cast(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] Add previous CFG block to BlockEntrance ProgramPoints (PR #140861)
balazs-benics-sonarsource wrote: /cc @necto https://github.com/llvm/llvm-project/pull/140861 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits