]> granicus.if.org Git - clang/commitdiff
Correctly propagate defaultedness across template instantiation. This
authorSean Hunt <scshunt@csclub.uwaterloo.ca>
Mon, 23 May 2011 21:07:59 +0000 (21:07 +0000)
committerSean Hunt <scshunt@csclub.uwaterloo.ca>
Mon, 23 May 2011 21:07:59 +0000 (21:07 +0000)
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

lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/CodeGenCXX/pr9965.cpp [new file with mode: 0644]

index 8bf7cb67b88a409a352294453081d14ecf4fe4d3..9d8ab641f1a718479bdf46fa0d8631b21a6d35a5 100644 (file)
@@ -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<CXXMethodDecl>(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);
index f6cce0bbf9c88455bb1b13432d566aa0979d78e5..fb34d9f1dad7cc89a833d684aae5c186353623e7 100644 (file)
@@ -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 (file)
index 0000000..b87fcf4
--- /dev/null
@@ -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