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;


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

Reply via email to