================ @@ -6298,10 +6334,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(), {}); ---------------- negativ wrote:
As I understand it (please correct me if I'm wrong), `FunctionDecl*` instances within the constructed `AS`T will be reused when building the `CFG` - if so, we could do something like: ```cpp if( FD->isAnalyzerNoReturn() || NoReturnFromCFG() ) { const_cast<FunctionDecl *>(FD)->addAttr(AnalyzerNoReturnAttr::Create( FD->getASTContext(), FD->getLocation())); return true; } ``` https://github.com/llvm/llvm-project/pull/146355 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits