forked from OSchip/llvm-project
Correctly propagate defaultedness across template instantiation. This
fixes PR9965, but we're not out of the water yet, as we do not successfully handle out-of-line definitions, due to my utter misunderstanding of how we manage templates. llvm-svn: 131920
This commit is contained in:
parent
6c4a319088
commit
1fb4e76218
|
@ -2997,7 +2997,8 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
|
||||||
// have inherited constructors.
|
// have inherited constructors.
|
||||||
DeclareInheritedConstructors(Record);
|
DeclareInheritedConstructors(Record);
|
||||||
|
|
||||||
CheckExplicitlyDefaultedMethods(Record);
|
if (!Record->isDependentType())
|
||||||
|
CheckExplicitlyDefaultedMethods(Record);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sema::CheckExplicitlyDefaultedMethods(CXXRecordDecl *Record) {
|
void Sema::CheckExplicitlyDefaultedMethods(CXXRecordDecl *Record) {
|
||||||
|
@ -8657,6 +8658,12 @@ void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) {
|
||||||
CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Dcl);
|
CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Dcl);
|
||||||
|
|
||||||
if (MD) {
|
if (MD) {
|
||||||
|
if (MD->getParent()->isDependentType()) {
|
||||||
|
MD->setDefaulted();
|
||||||
|
MD->setExplicitlyDefaulted();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CXXSpecialMember Member = getSpecialMember(MD);
|
CXXSpecialMember Member = getSpecialMember(MD);
|
||||||
if (Member == CXXInvalid) {
|
if (Member == CXXInvalid) {
|
||||||
Diag(DefaultLoc, diag::err_default_special_members);
|
Diag(DefaultLoc, diag::err_default_special_members);
|
||||||
|
|
|
@ -1264,6 +1264,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
|
||||||
PrincipalDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
|
PrincipalDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
|
||||||
PrincipalDecl->setNonMemberOperator();
|
PrincipalDecl->setNonMemberOperator();
|
||||||
|
|
||||||
|
assert(!D->isDefaulted() && "only methods should be defaulted");
|
||||||
return Function;
|
return Function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1496,7 +1497,14 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
|
||||||
else
|
else
|
||||||
Owner->addDecl(DeclToAdd);
|
Owner->addDecl(DeclToAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (D->isExplicitlyDefaulted()) {
|
||||||
|
SemaRef.SetDeclDefaulted(Method, Method->getLocation());
|
||||||
|
} else {
|
||||||
|
assert(!D->isDefaulted() &&
|
||||||
|
"should not implicitly default uninstantiated function");
|
||||||
|
}
|
||||||
|
|
||||||
return Method;
|
return Method;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
// RUN: %clang_cc1 -std=c++0x -emit-llvm -o - %s | FileCheck %s
|
||||||
|
template<typename T>
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
X() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
X<int> x;
|
||||||
|
// CHECK: define internal void @__cxx_global_var_init()
|
||||||
|
// CHECK: call void @_ZN1XIiEC1Ev
|
||||||
|
// CHECK: define linkonce_odr void @_ZN1XIiEC1Ev
|
||||||
|
// CHECK: define linkonce_odr void @_ZN1XIiEC2Ev
|
Loading…
Reference in New Issue