From: Sean Hunt Date: Mon, 23 May 2011 21:07:59 +0000 (+0000) Subject: Correctly propagate defaultedness across template instantiation. This X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=eb88ae5f9acdd17ec76fb83e151a77e25e4e8f31;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131920 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 8bf7cb67b8..9d8ab641f1 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2997,7 +2997,8 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) { // have inherited constructors. DeclareInheritedConstructors(Record); - CheckExplicitlyDefaultedMethods(Record); + if (!Record->isDependentType()) + CheckExplicitlyDefaultedMethods(Record); } void Sema::CheckExplicitlyDefaultedMethods(CXXRecordDecl *Record) { @@ -8657,6 +8658,12 @@ void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) { CXXMethodDecl *MD = dyn_cast(Dcl); if (MD) { + if (MD->getParent()->isDependentType()) { + MD->setDefaulted(); + MD->setExplicitlyDefaulted(); + return; + } + CXXSpecialMember Member = getSpecialMember(MD); if (Member == CXXInvalid) { Diag(DefaultLoc, diag::err_default_special_members); diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index f6cce0bbf9..fb34d9f1da 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1264,6 +1264,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, PrincipalDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary)) PrincipalDecl->setNonMemberOperator(); + assert(!D->isDefaulted() && "only methods should be defaulted"); return Function; } @@ -1496,7 +1497,14 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, else Owner->addDecl(DeclToAdd); } - + + if (D->isExplicitlyDefaulted()) { + SemaRef.SetDeclDefaulted(Method, Method->getLocation()); + } else { + assert(!D->isDefaulted() && + "should not implicitly default uninstantiated function"); + } + return Method; } diff --git a/test/CodeGenCXX/pr9965.cpp b/test/CodeGenCXX/pr9965.cpp new file mode 100644 index 0000000000..b87fcf4202 --- /dev/null +++ b/test/CodeGenCXX/pr9965.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -std=c++0x -emit-llvm -o - %s | FileCheck %s +template +struct X +{ + X() = default; +}; + +X 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