================
@@ -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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to