]> granicus.if.org Git - clang/commitdiff
Make sure that we're diagnosing duplicate explicit instantiation definitions.
authorDouglas Gregor <dgregor@apple.com>
Thu, 15 Oct 2009 18:07:02 +0000 (18:07 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 15 Oct 2009 18:07:02 +0000 (18:07 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84189 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplate.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/CXX/temp/temp.spec/p5.cpp [new file with mode: 0644]

index 8d7e199e7a8bcd2c0bf8453677ce5dc147fa9af2..730fea30b5aafbd6230c9f8f985c2db6bdeaf19d 100644 (file)
@@ -3818,8 +3818,11 @@ Sema::ActOnExplicitInstantiation(Scope *S,
   CheckExplicitInstantiationScope(*this, Record, NameLoc, true);
   
   // Verify that it is okay to explicitly instantiate here.
-  if (CXXRecordDecl *PrevDecl 
-        = cast_or_null<CXXRecordDecl>(Record->getPreviousDeclaration())) {
+  CXXRecordDecl *PrevDecl 
+    = cast_or_null<CXXRecordDecl>(Record->getPreviousDeclaration());
+  if (!PrevDecl && Record->getDefinition(Context))
+    PrevDecl = Record;
+  if (PrevDecl) {
     MemberSpecializationInfo *MSInfo = PrevDecl->getMemberSpecializationInfo();
     bool SuppressNew = false;
     assert(MSInfo && "No member specialization information?");
@@ -4065,6 +4068,9 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
   } 
   
   FunctionDecl *PrevDecl = Specialization->getPreviousDeclaration();
+  if (!PrevDecl && Specialization->isThisDeclarationADefinition())
+    PrevDecl = Specialization;
+
   if (PrevDecl) {
     bool SuppressNew = false;
     if (CheckSpecializationInstantiationRedecl(*this, D.getIdentifierLoc(), TSK,
index ca05d59abab9435ebfbcae91c2e04fe92900659d..4bbef29de0ba93d8f490e656dc1e20ec6e4a31b0 100644 (file)
@@ -1258,7 +1258,10 @@ void Sema::InstantiateStaticDataMemberDefinition(
 
   if (Var) {
     Var->setPreviousDeclaration(OldVar);
-    Var->setTemplateSpecializationKind(OldVar->getTemplateSpecializationKind());
+    MemberSpecializationInfo *MSInfo = OldVar->getMemberSpecializationInfo();
+    assert(MSInfo && "Missing member specialization information?");
+    Var->setTemplateSpecializationKind(MSInfo->getTemplateSpecializationKind(),
+                                       MSInfo->getPointOfInstantiation());
     DeclGroupRef DG(Var);
     Consumer.HandleTopLevelDecl(DG);
   }
diff --git a/test/CXX/temp/temp.spec/p5.cpp b/test/CXX/temp/temp.spec/p5.cpp
new file mode 100644 (file)
index 0000000..d5632e7
--- /dev/null
@@ -0,0 +1,29 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+template<typename T> inline void f(T) { }
+template void f(int); // expected-note{{previous explicit instantiation}}
+template void f(int); // expected-error{{duplicate explicit instantiation}}
+
+template<typename T>
+struct X0 {
+  union Inner { };
+  
+  void f(T) { }
+  
+  static T value;
+};
+
+template<typename T>
+T X0<T>::value = 3.14;
+
+template struct X0<int>; // expected-note{{previous explicit instantiation}}
+template struct X0<int>; // expected-error{{duplicate explicit instantiation}}
+
+template void X0<float>::f(float); // expected-note{{previous explicit instantiation}}
+template void X0<float>::f(float); // expected-error{{duplicate explicit instantiation}}
+
+template union X0<float>::Inner; // expected-note{{previous explicit instantiation}}
+template union X0<float>::Inner; // expected-error{{duplicate explicit instantiation}}
+
+template float X0<float>::value; // expected-note{{previous explicit instantiation}}
+template float X0<float>::value; // expected-error{{duplicate explicit instantiation}}