Author: Oleksandr T.
Date: 2025-11-19T17:35:47+02:00
New Revision: 93d759ce5a63cf74882087bad020825764043381

URL: 
https://github.com/llvm/llvm-project/commit/93d759ce5a63cf74882087bad020825764043381
DIFF: 
https://github.com/llvm/llvm-project/commit/93d759ce5a63cf74882087bad020825764043381.diff

LOG: [Clang] suppress -Wmissing-noreturn for virtual methods with throw-only 
bodies (#167523)

Fixes #167247

--- 

This PR addresses a case where Clang emitted `-Wmissing-noreturn` for
virtual methods whose body consists of a `throw` expression

```cpp
struct Base {
  virtual void foo() {
    throw std::runtime_error("error");
  }
};
```

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaDeclAttr.cpp
    clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c2da61e4d066a..f8a8fc3c0f450 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -434,6 +434,8 @@ Improvements to Clang's diagnostics
   or continue (#GH166013)
 - Clang now emits a diagnostic in case `vector_size` or `ext_vector_type`
   attributes are used with a negative size (#GH165463).
+- Clang no longer emits ``-Wmissing-noreturn`` for virtual methods where
+  the function body consists of a `throw` expression (#GH167247).
 
 Improvements to Clang's time-trace
 ----------------------------------

diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index bda7aa32a9348..c093052cf4035 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1966,8 +1966,16 @@ static bool isKnownToAlwaysThrow(const FunctionDecl *FD) 
{
   if (const auto *EWC = dyn_cast<ExprWithCleanups>(OnlyStmt)) {
     OnlyStmt = EWC->getSubExpr();
   }
-  // Check if the only statement is a throw expression.
-  return isa<CXXThrowExpr>(OnlyStmt);
+
+  if (isa<CXXThrowExpr>(OnlyStmt)) {
+    const auto *MD = dyn_cast<CXXMethodDecl>(FD);
+    if (MD && MD->isVirtual()) {
+      const auto *RD = MD->getParent();
+      return MD->hasAttr<FinalAttr>() || (RD && RD->isEffectivelyFinal());
+    }
+    return true;
+  }
+  return false;
 }
 
 void clang::inferNoReturnAttr(Sema &S, const Decl *D) {

diff  --git a/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp 
b/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp
index 06db972118d1c..2520c97cd0aee 100644
--- a/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp
+++ b/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp
@@ -53,3 +53,26 @@ int gnu_throws() {
 int cxx11_throws() {
     throw 0;
 }
+
+namespace GH167247 {
+struct S1 {
+  virtual ~S1() = default;
+  virtual void m() {
+    throw std::runtime_error("This method always throws");
+  }
+};
+
+struct S2 {
+  virtual ~S2() = default;
+
+  virtual void m() final { // expected-warning {{function 'm' could be 
declared with attribute 'noreturn'}}
+    throw std::runtime_error("This method always throws");
+  }
+};
+
+struct S3 final : S1 {
+  void m() { // expected-warning {{function 'm' could be declared with 
attribute 'noreturn'}}
+    throw std::runtime_error("This method always throws");
+  }
+};
+}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to