================ @@ -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; ---------------- negativ wrote:
> The use of static locals is a red-flag. Consider running gtests, where > multiple clang instances will be created in sequence, slowly filling up the > static cache with decl pointer that will get dangling after each test. Once > in a while after a long running unittest you would get a cache hit for a > dangling pointer and the disaster happens. I've revisited the approach I initially took, so now we don't need any cache to collect visited functions as I added an implicit bool argument to the `analyzer_noreturn` attribute. These declarations are now considered equivalent: ```cpp void foo() __attribute__((analyzer_noreturn)); void foo() __attribute__((analyzer_noreturn(true))); ``` ...and I can add implicit `__attribute__((analyzer_noreturn(false)))` to functions that I've already checked. This gives us the following benefits: - We don't need to revisit function calls repeatedly since the result of the previous check is saved in the analyzer_noreturn attribute - Simplifies DFS search (nodes we're currently visiting are marked with` analyzer_noreturn(false)`) 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