[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 07:55:04 PDT 2025
================
@@ -6298,10 +6308,60 @@ 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;
+
+ auto *FD = CE->getDirectCallee();
+
+ if (!FD)
+ return false;
+
+ auto *CanCD = FD->getCanonicalDecl();
+ auto *DefFD = CanCD->getDefinition();
+ auto NoRetAttrOpt = CanCD->getAnalyzerNoReturn();
+ auto NoReturn = false;
+
+ if (!NoRetAttrOpt && DefFD && DefFD->getBody()) {
+ // HACK: we are gonna cache analysis result as implicit
+ // `analyzer_noreturn` attribute
+ auto *MutCD = const_cast<FunctionDecl *>(CanCD);
----------------
negativ wrote:
I don't think we should treat recursive calls as creating 'no-return' sinks - it would make the `CFG` logic way too complex, and from my perspective, `CFG` wasn't built for this kind of analysis anyway. My simple implementation already feels like a hack since `CFG` was never supposed to do inter-procedural stuff. :D
https://github.com/llvm/llvm-project/pull/146355
More information about the cfe-commits
mailing list