diff options
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index d27f767..215431c 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -9546,14 +9546,32 @@ bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall( CXXMethodDecl *Decl = SMOR.getMethod(); FieldDecl *Field = Subobj.dyn_cast<FieldDecl*>(); - int DiagKind = -1; - - if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::NoMemberOrDeleted) - DiagKind = !Decl ? 0 : 1; - else if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::Ambiguous) - DiagKind = 2; + enum { + NotSet = -1, + NoDecl, + DeletedDecl, + MultipleDecl, + InaccessibleDecl, + NonTrivialDecl + } DiagKind = NotSet; + + if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::NoMemberOrDeleted) { + if (CSM == CXXSpecialMemberKind::DefaultConstructor && 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()) + return false; + } + DiagKind = !Decl ? NoDecl : DeletedDecl; + } else if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::Ambiguous) + DiagKind = MultipleDecl; else if (!isAccessible(Subobj, Decl)) - DiagKind = 3; + DiagKind = InaccessibleDecl; else if (!IsDtorCallInCtor && Field && Field->getParent()->isUnion() && !Decl->isTrivial()) { // A member of a union must have a trivial corresponding special member. @@ -9569,13 +9587,13 @@ bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall( // initializer const auto *RD = cast<CXXRecordDecl>(Field->getParent()); if (!RD->hasInClassInitializer()) - DiagKind = 4; + DiagKind = NonTrivialDecl; } else { - DiagKind = 4; + DiagKind = NonTrivialDecl; } } - if (DiagKind == -1) + if (DiagKind == NotSet) return false; if (Diagnose) { @@ -9593,9 +9611,9 @@ bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall( << /*IsObjCPtr*/ false; } - if (DiagKind == 1) + if (DiagKind == DeletedDecl) S.NoteDeletedFunction(Decl); - // FIXME: Explain inaccessibility if DiagKind == 3. + // FIXME: Explain inaccessibility if DiagKind == InaccessibleDecl. } return true; |