forked from OSchip/llvm-project
The presence of a user-*declared* constructor makes the default
constructor not user provided (and, therefore, non-trivial). Fixes <rdar://problem/11736429>. llvm-svn: 162947
This commit is contained in:
parent
7578a47fb8
commit
a3d3fe9be6
|
@ -9507,12 +9507,12 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If the given constructor is user-provided, produce a diagnostic explaining
|
/// If the given constructor is user-declared, produce a diagnostic explaining
|
||||||
/// that it makes the class non-trivial.
|
/// that it makes the class non-trivial.
|
||||||
static bool DiagnoseNontrivialUserProvidedCtor(Sema &S, QualType QT,
|
static bool diagnoseNonTrivialUserDeclaredCtor(Sema &S, QualType QT,
|
||||||
CXXConstructorDecl *CD,
|
CXXConstructorDecl *CD,
|
||||||
Sema::CXXSpecialMember CSM) {
|
Sema::CXXSpecialMember CSM) {
|
||||||
if (!CD->isUserProvided())
|
if (CD->isImplicit())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SourceLocation CtorLoc = CD->getLocation();
|
SourceLocation CtorLoc = CD->getLocation();
|
||||||
|
@ -9535,17 +9535,17 @@ void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) {
|
||||||
if (RD->hasUserDeclaredConstructor()) {
|
if (RD->hasUserDeclaredConstructor()) {
|
||||||
typedef CXXRecordDecl::ctor_iterator ctor_iter;
|
typedef CXXRecordDecl::ctor_iterator ctor_iter;
|
||||||
for (ctor_iter CI = RD->ctor_begin(), CE = RD->ctor_end(); CI != CE; ++CI)
|
for (ctor_iter CI = RD->ctor_begin(), CE = RD->ctor_end(); CI != CE; ++CI)
|
||||||
if (DiagnoseNontrivialUserProvidedCtor(*this, QT, *CI, member))
|
if (diagnoseNonTrivialUserDeclaredCtor(*this, QT, *CI, member))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// No user-provided constructors; look for constructor templates.
|
// No user-delcared constructors; look for constructor templates.
|
||||||
typedef CXXRecordDecl::specific_decl_iterator<FunctionTemplateDecl>
|
typedef CXXRecordDecl::specific_decl_iterator<FunctionTemplateDecl>
|
||||||
tmpl_iter;
|
tmpl_iter;
|
||||||
for (tmpl_iter TI(RD->decls_begin()), TE(RD->decls_end());
|
for (tmpl_iter TI(RD->decls_begin()), TE(RD->decls_end());
|
||||||
TI != TE; ++TI) {
|
TI != TE; ++TI) {
|
||||||
CXXConstructorDecl *CD =
|
CXXConstructorDecl *CD =
|
||||||
dyn_cast<CXXConstructorDecl>(TI->getTemplatedDecl());
|
dyn_cast<CXXConstructorDecl>(TI->getTemplatedDecl());
|
||||||
if (CD && DiagnoseNontrivialUserProvidedCtor(*this, QT, CD, member))
|
if (CD && diagnoseNonTrivialUserDeclaredCtor(*this, QT, CD, member))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -362,3 +362,14 @@ namespace AssignOpUnion {
|
||||||
b y; // expected-warning {{union member 'y' with a non-trivial copy assignment operator is incompatible with C++98}}
|
b y; // expected-warning {{union member 'y' with a non-trivial copy assignment operator is incompatible with C++98}}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace rdar11736429 {
|
||||||
|
struct X {
|
||||||
|
X(const X&) = delete; // expected-warning{{deleted function definitions are incompatible with C++98}} \
|
||||||
|
// expected-note{{because type 'rdar11736429::X' has a user-declared constructor}}
|
||||||
|
};
|
||||||
|
|
||||||
|
union S {
|
||||||
|
X x; // expected-warning{{union member 'x' with a non-trivial constructor is incompatible with C++98}}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue