[clang] [Clang][Sema] Fix incorrect rejection default construction of union with nontrivial member (PR #82407)

Shafik Yaghmour via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 20 13:55:50 PST 2024


================
@@ -9442,9 +9442,21 @@ bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
 
   int DiagKind = -1;
 
-  if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::NoMemberOrDeleted)
-    DiagKind = !Decl ? 0 : 1;
-  else if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::Ambiguous)
+  if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::NoMemberOrDeleted) {
+    if (CSM == Sema::CXXDefaultConstructor && Field &&
+        Field->getParent()->isUnion()) {
+      // [class.default.ctor]p2:
+      //   A defaulted default constructor for class X is defined as deleted if
+      //   - X is a union that has a variant member with a non-trivial default
+      //     constructor and no variant member of X has a default member
+      //     initializer
+      const auto *RD = cast<CXXRecordDecl>(Field->getParent());
+      if (!RD->hasInClassInitializer())
+        DiagKind = !Decl ? 0 : 1;
----------------
shafik wrote:

I have three different states I need to check, I can remove a check by setting `DiagKind` unconditionally and then check `if(RD->hasInClassInitializer())` instead and in that case set it back to `-1` but that does not express the intent as clearly. So I think what I have now is more maintainable although slightly more verbose. 

https://github.com/llvm/llvm-project/pull/82407


More information about the cfe-commits mailing list