https://github.com/a-tarasyuk created 
https://github.com/llvm/llvm-project/pull/184048

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.

>From e287eee4d609ea87337d0a0e8317c9f00a772a86 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <[email protected]>
Date: Mon, 2 Mar 2026 00:58:56 +0200
Subject: [PATCH] [Clang] prevent constexpr crash on invalid overrides

---
 clang/docs/ReleaseNotes.rst                   |  1 +
 clang/lib/Sema/SemaDecl.cpp                   |  9 ++++---
 .../SemaCXX/constant-expression-cxx14.cpp     | 26 +++++++++++++++++++
 3 files changed, 33 insertions(+), 3 deletions(-)

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@+1 {{expected class name}}
+struct B : sizeof(int[c]) {};
+
+struct C {
+  B b;
+  // expected-note@+1 {{overridden virtual function is here}}
+  virtual const A *d() const;
+};
+
+struct D : C {
+  // expected-error@+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@+1 {{static assertion expression is not an integral constant 
expression}}
+static_assert(f->d()->b == 'Z', "");
+}

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

Reply via email to