@@ -9546,14 +9546,32 @@ bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
9546
9546
CXXMethodDecl *Decl = SMOR.getMethod();
9547
9547
FieldDecl *Field = Subobj.dyn_cast<FieldDecl*>();
9548
9548
9549
- int DiagKind = -1;
9550
-
9551
- if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::NoMemberOrDeleted)
9552
- DiagKind = !Decl ? 0 : 1;
9553
- else if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::Ambiguous)
9554
- DiagKind = 2;
9549
+ enum {
9550
+ NotSet = -1,
9551
+ NoDecl,
9552
+ DeletedDecl,
9553
+ MultipleDecl,
9554
+ InaccessibleDecl,
9555
+ NonTrivialDecl
9556
+ } DiagKind = NotSet;
9557
+
9558
+ if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::NoMemberOrDeleted) {
9559
+ if (CSM == CXXSpecialMemberKind::DefaultConstructor && Field &&
9560
+ Field->getParent()->isUnion()) {
9561
+ // [class.default.ctor]p2:
9562
+ // A defaulted default constructor for class X is defined as deleted if
9563
+ // - X is a union that has a variant member with a non-trivial default
9564
+ // constructor and no variant member of X has a default member
9565
+ // initializer
9566
+ const auto *RD = cast<CXXRecordDecl>(Field->getParent());
9567
+ if (RD->hasInClassInitializer())
9568
+ return false;
9569
+ }
9570
+ DiagKind = !Decl ? NoDecl : DeletedDecl;
9571
+ } else if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::Ambiguous)
9572
+ DiagKind = MultipleDecl;
9555
9573
else if (!isAccessible(Subobj, Decl))
9556
- DiagKind = 3 ;
9574
+ DiagKind = InaccessibleDecl ;
9557
9575
else if (!IsDtorCallInCtor && Field && Field->getParent()->isUnion() &&
9558
9576
!Decl->isTrivial()) {
9559
9577
// A member of a union must have a trivial corresponding special member.
@@ -9569,13 +9587,13 @@ bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
9569
9587
// initializer
9570
9588
const auto *RD = cast<CXXRecordDecl>(Field->getParent());
9571
9589
if (!RD->hasInClassInitializer())
9572
- DiagKind = 4 ;
9590
+ DiagKind = NonTrivialDecl ;
9573
9591
} else {
9574
- DiagKind = 4 ;
9592
+ DiagKind = NonTrivialDecl ;
9575
9593
}
9576
9594
}
9577
9595
9578
- if (DiagKind == -1 )
9596
+ if (DiagKind == NotSet )
9579
9597
return false;
9580
9598
9581
9599
if (Diagnose) {
@@ -9593,9 +9611,9 @@ bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
9593
9611
<< /*IsObjCPtr*/ false;
9594
9612
}
9595
9613
9596
- if (DiagKind == 1 )
9614
+ if (DiagKind == DeletedDecl )
9597
9615
S.NoteDeletedFunction(Decl);
9598
- // FIXME: Explain inaccessibility if DiagKind == 3 .
9616
+ // FIXME: Explain inaccessibility if DiagKind == InaccessibleDecl .
9599
9617
}
9600
9618
9601
9619
return true;
0 commit comments