diff options
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 72516fda80..cc19ce9959 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -9735,13 +9735,18 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) { // copy constructors. CXXSpecialMember member = CXXInvalid; - if (!RDecl->hasTrivialCopyConstructor()) + // We're required to check for any non-trivial constructors. Since the + // implicit default constructor is suppressed if there are any + // user-declared constructors, we just need to check that there is a + // trivial default constructor and a trivial copy constructor. (We don't + // worry about move constructors here, since this is a C++98 check.) + if (RDecl->hasNonTrivialCopyConstructor()) member = CXXCopyConstructor; else if (!RDecl->hasTrivialDefaultConstructor()) member = CXXDefaultConstructor; - else if (!RDecl->hasTrivialCopyAssignment()) + else if (RDecl->hasNonTrivialCopyAssignment()) member = CXXCopyAssignment; - else if (!RDecl->hasTrivialDestructor()) + else if (RDecl->hasNonTrivialDestructor()) member = CXXDestructor; if (member != CXXInvalid) { @@ -9789,6 +9794,8 @@ static bool diagnoseNonTrivialUserDeclaredCtor(Sema &S, QualType QT, /// DiagnoseNontrivial - Given that a class has a non-trivial /// special member, figure out why. +/// FIXME: These checks are not correct in C++11 mode. Currently, this is OK +/// since we only use this in C++11 for a -Wc++98-compat warning. void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) { QualType QT(T, 0U); CXXRecordDecl* RD = cast<CXXRecordDecl>(T->getDecl()); @@ -9887,17 +9894,21 @@ void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) { } } - bool (CXXRecordDecl::*hasTrivial)() const; + bool (CXXRecordDecl::*hasNonTrivial)() const; switch (member) { case CXXDefaultConstructor: - hasTrivial = &CXXRecordDecl::hasTrivialDefaultConstructor; break; + hasNonTrivial = &CXXRecordDecl::hasNonTrivialDefaultConstructor; break; case CXXCopyConstructor: - hasTrivial = &CXXRecordDecl::hasTrivialCopyConstructor; break; + hasNonTrivial = &CXXRecordDecl::hasNonTrivialCopyConstructor; break; case CXXCopyAssignment: - hasTrivial = &CXXRecordDecl::hasTrivialCopyAssignment; break; + hasNonTrivial = &CXXRecordDecl::hasNonTrivialCopyAssignment; break; + case CXXMoveConstructor: + hasNonTrivial = &CXXRecordDecl::hasNonTrivialMoveConstructor; break; + case CXXMoveAssignment: + hasNonTrivial = &CXXRecordDecl::hasNonTrivialMoveAssignment; break; case CXXDestructor: - hasTrivial = &CXXRecordDecl::hasTrivialDestructor; break; - default: + hasNonTrivial = &CXXRecordDecl::hasNonTrivialDestructor; break; + case CXXInvalid: llvm_unreachable("unexpected special member"); } @@ -9906,7 +9917,7 @@ void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) { const RecordType *BaseRT = bi->getType()->getAs<RecordType>(); assert(BaseRT && "Don't know how to handle dependent bases"); CXXRecordDecl *BaseRecTy = cast<CXXRecordDecl>(BaseRT->getDecl()); - if (!(BaseRecTy->*hasTrivial)()) { + if ((BaseRecTy->*hasNonTrivial)()) { SourceLocation BaseLoc = bi->getLocStart(); Diag(BaseLoc, diag::note_nontrivial_has_nontrivial) << QT << 1 << member; DiagnoseNontrivial(BaseRT, member); @@ -9922,7 +9933,7 @@ void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) { if (const RecordType *EltRT = EltTy->getAs<RecordType>()) { CXXRecordDecl* EltRD = cast<CXXRecordDecl>(EltRT->getDecl()); - if (!(EltRD->*hasTrivial)()) { + if ((EltRD->*hasNonTrivial)()) { SourceLocation FLoc = fi->getLocation(); Diag(FLoc, diag::note_nontrivial_has_nontrivial) << QT << 0 << member; DiagnoseNontrivial(EltRT, member); @@ -9945,8 +9956,6 @@ void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) { } } } - - llvm_unreachable("found no explanation for non-trivial member"); } /// TranslateIvarVisibility - Translate visibility from a token ID to an |