[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