aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-02-26 10:50:32 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-02-26 10:50:32 +0000
commitea7c1e24f33c554aeac07dc4f6dc7493dd98e272 (patch)
tree40ff151ca0fb89cb407b99d568831878a678c82b /lib/Sema/SemaDecl.cpp
parent2229d5731032617acc6aa30657ce03423fb02083 (diff)
Don't assert when trying to diagnose why a class with a constructor template is
non-trivial. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151486 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp34
1 files changed, 25 insertions, 9 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 05136b882b..f091d858b5 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -8935,6 +8935,19 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) {
return false;
}
+/// If the given constructor is user-provided, produce a diagnostic explaining
+/// that it makes the class non-trivial.
+static bool DiagnoseNontrivialUserProvidedCtor(Sema &S, QualType QT,
+ CXXConstructorDecl *CD,
+ Sema::CXXSpecialMember CSM) {
+ if (!CD->isUserProvided())
+ return false;
+
+ SourceLocation CtorLoc = CD->getLocation();
+ S.Diag(CtorLoc, diag::note_nontrivial_user_defined) << QT << CSM;
+ return true;
+}
+
/// DiagnoseNontrivial - Given that a class has a non-trivial
/// special member, figure out why.
void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) {
@@ -8949,17 +8962,20 @@ void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) {
case CXXDefaultConstructor:
if (RD->hasUserDeclaredConstructor()) {
typedef CXXRecordDecl::ctor_iterator ctor_iter;
- for (ctor_iter ci = RD->ctor_begin(), ce = RD->ctor_end(); ci != ce;++ci){
- const FunctionDecl *body = 0;
- ci->hasBody(body);
- if (!body || !cast<CXXConstructorDecl>(body)->isImplicitlyDefined()) {
- SourceLocation CtorLoc = ci->getLocation();
- Diag(CtorLoc, diag::note_nontrivial_user_defined) << QT << member;
+ for (ctor_iter CI = RD->ctor_begin(), CE = RD->ctor_end(); CI != CE; ++CI)
+ if (DiagnoseNontrivialUserProvidedCtor(*this, QT, *CI, member))
return;
- }
- }
- llvm_unreachable("found no user-declared constructors");
+ // No user-provided constructors; look for constructor templates.
+ typedef CXXRecordDecl::specific_decl_iterator<FunctionTemplateDecl>
+ tmpl_iter;
+ for (tmpl_iter TI(RD->decls_begin()), TE(RD->decls_end());
+ TI != TE; ++TI) {
+ CXXConstructorDecl *CD =
+ dyn_cast<CXXConstructorDecl>(TI->getTemplatedDecl());
+ if (CD && DiagnoseNontrivialUserProvidedCtor(*this, QT, CD, member))
+ return;
+ }
}
break;