[clang] [clang-tools-extra] [clang]: Propagate `*noreturn` attributes in `CFG` (PR #146355)
Andrey Karlov via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 15 02:57:31 PDT 2025
================
@@ -6298,10 +6304,43 @@ static bool isImmediateSinkBlock(const CFGBlock *Blk) {
// at least for now, but once we have better support for exceptions,
// we'd need to carefully handle the case when the throw is being
// immediately caught.
- if (llvm::any_of(*Blk, [](const CFGElement &Elm) {
+ if (llvm::any_of(*Blk, [](const CFGElement &Elm) -> bool {
+ if (std::optional<CFGStmt> StmtElm = Elm.getAs<CFGStmt>())
+ return isa<CXXThrowExpr>(StmtElm->getStmt());
+ return false;
+ }))
+ return true;
+
+ auto HasNoReturnCall = [](const CallExpr *CE) {
+ if (!CE)
+ return false;
+
+ static thread_local llvm::SmallPtrSet<const FunctionDecl *, 32> InProgress;
+
+ auto *FD = CE->getDirectCallee();
+
+ if (!FD || InProgress.count(FD))
+ return false;
+
+ InProgress.insert(FD);
+ auto DoCleanup = llvm::make_scope_exit([&]() { InProgress.erase(FD); });
+
+ auto NoReturnFromCFG = [FD]() {
+ if (!FD->getBody())
+ return false;
+
+ auto CalleeCFG =
+ CFG::buildCFG(FD, FD->getBody(), &FD->getASTContext(), {});
+
+ return CalleeCFG && CalleeCFG->getEntry().isInevitablySinking();
+ };
+
+ return FD->isAnalyzerNoReturn() || NoReturnFromCFG();
----------------
negativ wrote:
> What if we have redecls, does it matter which has the attribute, or do we always bind the attribute to the canonical decl?
Switched to using canonical decl for `analyzer_noreturn` lookup & caching. BTW: since `AnalyzerNoReturnAttr` inherits from `InheritableAttr`, we can check any function decl.
https://github.com/llvm/llvm-project/pull/146355
More information about the cfe-commits
mailing list