aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp35
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