[clang] [Clang] prevent constexpr crash on invalid overrides (PR #184048)

via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 2 02:42:19 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Oleksandr Tarasiuk (a-tarasyuk)

<details>
<summary>Changes</summary>

Fixes #<!-- -->183290

---

This PR fixes a crash during `constexpr` evaluation that occurred after detecting an invalid override. It now marks the overriding method as invalid when override checks fail.

---
Full diff: https://github.com/llvm/llvm-project/pull/184048.diff


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+1) 
- (modified) clang/lib/Sema/SemaDecl.cpp (+6-3) 
- (modified) clang/test/SemaCXX/constant-expression-cxx14.cpp (+26) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index fe268ef2133b5..b9a5708cb4301 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -305,6 +305,7 @@ Bug Fixes in This Version
 - Fixed an assertion failure in the serialized diagnostic printer when it is destroyed without calling ``finish()``. (#GH140433)
 - Fixed an assertion failure caused by error recovery while extending a nested name specifier with results from ordinary lookup. (#GH181470)
 - Fixed a crash when parsing ``#pragma clang attribute`` arguments for attributes that forbid arguments. (#GH182122)
+- Fixed a crash where constexpr evaluation encountered invalid overrides. (#GH183290)
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 3db91b00f9d80..76aa85ab6f89d 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9247,9 +9247,12 @@ bool Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) {
         continue;
       if (Overridden.insert(BaseMD).second) {
         MD->addOverriddenMethod(BaseMD);
-        CheckOverridingFunctionReturnType(MD, BaseMD);
-        CheckOverridingFunctionAttributes(MD, BaseMD);
-        CheckOverridingFunctionExceptionSpec(MD, BaseMD);
+        bool Invalid = false;
+        Invalid |= CheckOverridingFunctionReturnType(MD, BaseMD);
+        Invalid |= CheckOverridingFunctionAttributes(MD, BaseMD);
+        Invalid |= CheckOverridingFunctionExceptionSpec(MD, BaseMD);
+        if (Invalid)
+          MD->setInvalidDecl();
         CheckIfOverriddenFunctionIsMarkedFinal(MD, BaseMD);
       }
 
diff --git a/clang/test/SemaCXX/constant-expression-cxx14.cpp b/clang/test/SemaCXX/constant-expression-cxx14.cpp
index 68e15985d97b8..a917837410ee5 100644
--- a/clang/test/SemaCXX/constant-expression-cxx14.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx14.cpp
@@ -1456,3 +1456,29 @@ constexpr bool missingCase() {
     1u: return false; // expected-error {{expected 'case' keyword before expression}}
   }
 }
+
+namespace GH183290 {
+struct A {
+  constexpr char a() const { return 'Z'; }
+  char b = a();
+};
+
+// expected-error at +1 {{expected class name}}
+struct B : sizeof(int[c]) {};
+
+struct C {
+  B b;
+  // expected-note at +1 {{overridden virtual function is here}}
+  virtual const A *d() const;
+};
+
+struct D : C {
+  // expected-error at +1 {{return type of virtual function 'd' is not covariant with the return type of the function it overrides ('const B *' is not derived from 'const A *')}}
+  constexpr virtual const B *d() const { return &this->b; }
+};
+
+constexpr D e;
+constexpr const C *f = &e;
+// expected-error at +1 {{static assertion expression is not an integral constant expression}}
+static_assert(f->d()->b == 'Z', "");
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/184048


More information about the cfe-commits mailing list