@@ -624,34 +624,8 @@ struct CheckFallThroughDiagnostics {
624624 }
625625};
626626
627- // FIXME: This is a shallow best-effort check. Currently, we only handle
628- // cases where the function body consists of a single `throw` expression,
629- // possibly wrapped in an `ExprWithCleanups`. We do not perform general
630- // control-flow analysis or handle more complex throwing patterns.
631- // Consider expanding this to handle more cases in the future.
632- bool isKnownToAlwaysThrow (const FunctionDecl *FD) {
633- if (!FD->hasBody ())
634- return false ;
635- const Stmt *Body = FD->getBody ();
636- const Stmt *OnlyStmt = nullptr ;
637-
638- if (const auto *Compound = dyn_cast<CompoundStmt>(Body)) {
639- if (Compound->size () != 1 )
640- return false ; // More than one statement, can't be known to always throw.
641- OnlyStmt = *Compound->body_begin ();
642- } else {
643- OnlyStmt = Body;
644- }
645-
646- // Unwrap ExprWithCleanups if necessary.
647- if (const auto *EWC = dyn_cast<ExprWithCleanups>(OnlyStmt)) {
648- OnlyStmt = EWC->getSubExpr ();
649- }
650- // Check if the only statement is a throw expression.
651- return isa<CXXThrowExpr>(OnlyStmt);
652- }
653-
654627} // anonymous namespace
628+
655629// / CheckFallThroughForBody - Check that we don't fall off the end of a
656630// / function that should return a value. Check that we don't fall off the end
657631// / of a noreturn function. We assume that functions and blocks not marked
@@ -669,7 +643,7 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
669643 ReturnsVoid = CBody->getFallthroughHandler () != nullptr ;
670644 else
671645 ReturnsVoid = FD->getReturnType ()->isVoidType ();
672- HasNoReturn = FD->isNoReturn ();
646+ HasNoReturn = FD->isNoReturn () || FD-> hasAttr <InferredNoReturnAttr>() ;
673647 }
674648 else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
675649 ReturnsVoid = MD->getReturnType ()->isVoidType ();
@@ -719,7 +693,7 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
719693 }
720694 if (const auto *CE = dyn_cast<CallExpr>(LastStmt)) {
721695 if (const FunctionDecl *Callee = CE->getDirectCallee ();
722- Callee && isKnownToAlwaysThrow ( Callee)) {
696+ Callee && Callee-> hasAttr <InferredNoReturnAttr>( )) {
723697 return ; // Don't warn about fall-through.
724698 }
725699 }
0 commit comments