[clang] [Clang] prevent constexpr crash on invalid overrides (PR #184048)
Oleksandr Tarasiuk via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 11 10:40:58 PDT 2026
https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/184048
>From e287eee4d609ea87337d0a0e8317c9f00a772a86 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
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 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', "");
+}
More information about the cfe-commits
mailing list