[clang] 330b40e - [Analysis] Prevent revisiting block when searching for noreturn vars (#150582)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 30 06:40:10 PDT 2025
Author: Serge Pavlov
Date: 2025-07-30T20:40:07+07:00
New Revision: 330b40e11fd20e9a29b9c24de17e4ba23afeedc6
URL: https://github.com/llvm/llvm-project/commit/330b40e11fd20e9a29b9c24de17e4ba23afeedc6
DIFF: https://github.com/llvm/llvm-project/commit/330b40e11fd20e9a29b9c24de17e4ba23afeedc6.diff
LOG: [Analysis] Prevent revisiting block when searching for noreturn vars (#150582)
When searching for noreturn variable initializations, do not visit CFG
blocks that are already visited, it prevents hanging the analysis.
It must fix https://github.com/llvm/llvm-project/issues/150336.
Added:
clang/test/SemaCXX/noreturn-weverything.c
Modified:
clang/lib/Sema/AnalysisBasedWarnings.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 829c81bab16f5..35ad0b59ad0fc 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -503,8 +503,12 @@ static bool areAllValuesNoReturn(const VarDecl *VD, const CFGBlock &VarBlk,
TransferFunctions TF(VD);
BackwardDataflowWorklist Worklist(*AC.getCFG(), AC);
+ llvm::DenseSet<const CFGBlock *> Visited;
Worklist.enqueueBlock(&VarBlk);
while (const CFGBlock *B = Worklist.dequeue()) {
+ if (Visited.contains(B))
+ continue;
+ Visited.insert(B);
// First check the current block.
for (CFGBlock::const_reverse_iterator ri = B->rbegin(), re = B->rend();
ri != re; ++ri) {
diff --git a/clang/test/SemaCXX/noreturn-weverything.c b/clang/test/SemaCXX/noreturn-weverything.c
new file mode 100644
index 0000000000000..92a587d395639
--- /dev/null
+++ b/clang/test/SemaCXX/noreturn-weverything.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only %s -Weverything
+
+void free(void *);
+typedef void (*set_free_func)(void *);
+struct Method {
+ int nparams;
+ int *param;
+};
+void selelem_free_method(struct Method* method, void* data) {
+ set_free_func free_func = 0;
+ for (int i = 0; i < method->nparams; ++i)
+ free(&method->param[i]);
+ if (data && free_func)
+ free_func(data);
+}
More information about the cfe-commits
mailing list