[clang] 1f713c0 - [Clang] Fixed an assertion in constant evaluation when using a defaulted comparison operator in a union (#198830)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 24 19:27:39 PDT 2026
Author: TPPPP
Date: 2026-06-25T10:27:34+08:00
New Revision: 1f713c05e87e470cbdb5c5eee5bcbc0d46ba342b
URL: https://github.com/llvm/llvm-project/commit/1f713c05e87e470cbdb5c5eee5bcbc0d46ba342b
DIFF: https://github.com/llvm/llvm-project/commit/1f713c05e87e470cbdb5c5eee5bcbc0d46ba342b.diff
LOG: [Clang] Fixed an assertion in constant evaluation when using a defaulted comparison operator in a union (#198830)
Fixes an assertion failure by decoupling `IsTrivialMemoryOperation` from
assignment operators.
fix #147127
Added:
clang/test/SemaCXX/gh147127.cpp
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/AST/ExprConstant.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4ca239ca5f2e4..5eea73ad9dc83 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -731,6 +731,7 @@ Bug Fixes in This Version
EOF handling from accidentally restoring CLK_CachingLexer while a tentative parse is still active, which could trigger a caching lexer re-entry assertion
in clangd signature help. (#GH200677)
- Fixed a crash when ``#embed`` is used with C++ modules (#GH195350)
+- Fixed an assertion in constant evaluation when using a defaulted comparison operator in a ``union``. (#GH147127)
- Fixed a bug where ``-x cuda`` caused clang to immediately resolve templates that should not be. (#GH200545)
- Fixed an issue where ``__typeof_unqual`` and ``__typeof_unqual__`` were rejected as a declaration specifier in block scope in C++.
- Fixed crash when checking for overflow for unary operator that can't overflow (#GH170072)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index b628669880f2b..5ee27dd4e2ba2 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -7016,13 +7016,20 @@ static bool HandleFunctionCall(SourceLocation CallLoc,
// Skip this for non-union classes with no fields; in that case, the defaulted
// copy/move does not actually read the object.
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Callee);
- if (MD && MD->isDefaulted() &&
- (MD->getParent()->isUnion() ||
- (MD->isTrivial() &&
- isReadByLvalueToRvalueConversion(MD->getParent())))) {
+
+ auto IsTrivialMemoryOperation = [&](const CXXMethodDecl *MD) {
+ if (!MD || !MD->isDefaulted())
+ return false;
+ if (!MD->isCopyAssignmentOperator() && !MD->isMoveAssignmentOperator())
+ return false;
+ return MD->getParent()->isUnion() ||
+ (MD->isTrivial() &&
+ isReadByLvalueToRvalueConversion(MD->getParent()));
+ };
+
+ if (IsTrivialMemoryOperation(MD)) {
unsigned ExplicitOffset = MD->isExplicitObjectMemberFunction() ? 1 : 0;
- assert(ObjectArg &&
- (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()));
+ assert(ObjectArg);
APValue RHSValue;
if (!handleTrivialCopy(Info, MD->getParamDecl(0), Args[0], RHSValue,
MD->getParent()->isUnion()))
diff --git a/clang/test/SemaCXX/gh147127.cpp b/clang/test/SemaCXX/gh147127.cpp
new file mode 100644
index 0000000000000..35bdc663c798f
--- /dev/null
+++ b/clang/test/SemaCXX/gh147127.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++20-extensions -verify=cxx17 %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify=cxx20 %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++20-extensions -fexperimental-new-constant-interpreter -verify=cxx17 %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -fexperimental-new-constant-interpreter -verify=cxx20 %s
+
+union A {
+ // cxx20-no-diagnostics
+ bool operator==(const A&) const = default; // cxx17-warning {{defaulted comparison operators are a C++20 extension}}
+};
+
+A a;
+bool b = a == a;
More information about the cfe-commits
mailing list