[clang] [clang-tools-extra] [clang]: Propagate `*noreturn` attributes in `CFG` (PR #146355)
Andrey Karlov via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 18 01:20:53 PDT 2025
================
@@ -6298,10 +6304,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);
+
+ // Mark function as `analyzer_noreturn(false)` to:
+ // * prevent infinite recursion in noreturn analysis
+ // * indicate that we've already analyzed(-ing) this function
+ // * serve as a safe default assumption (function may return)
+ MutCD->addAttr(AnalyzerNoReturnAttr::CreateImplicit(
+ CanCD->getASTContext(), false, CanCD->getLocation()));
+
+ auto CalleeCFG =
+ CFG::buildCFG(DefFD, DefFD->getBody(), &DefFD->getASTContext(), {});
+
+ NoReturn = CalleeCFG && CalleeCFG->getEntry().isInevitablySinking();
+
+ // Override to `analyzer_noreturn(true)`
+ if (NoReturn) {
+ MutCD->dropAttr<AnalyzerNoReturnAttr>();
+ MutCD->addAttr(AnalyzerNoReturnAttr::CreateImplicit(
+ CanCD->getASTContext(), NoReturn, CanCD->getLocation()));
----------------
negativ wrote:
We will drop this attribute only if we've created it before:
```cpp
auto *CanCD = FD->getCanonicalDecl();
auto *DefFD = CanCD->getDefinition();
auto NoRetAttrOpt = CanCD->getAnalyzerNoReturn();
auto NoReturn = false;
if (!NoRetAttrOpt && DefFD && DefFD->getBody()) {
...
// Override to `analyzer_noreturn(true)`
if (NoReturn) {
```
https://github.com/llvm/llvm-project/pull/146355
More information about the cfe-commits
mailing list