]> granicus.if.org Git - clang/commitdiff
Only perform an implicit instantiation of a function if its template
authorDouglas Gregor <dgregor@apple.com>
Thu, 8 Oct 2009 00:14:38 +0000 (00:14 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 8 Oct 2009 00:14:38 +0000 (00:14 +0000)
specialization kind is TSK_ImplicitInstantiation. Previously, we would
end up implicitly instantiating functions that had explicit
specialization declarations or explicit instantiation declarations
(with no corresponding definitions).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83511 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp

index e7b074b43c3a84ccf55724bf04646fb31c4db0bf..3bd72d07d2e195db930c1ed50a2c70396aadd6ec 100644 (file)
@@ -6198,15 +6198,9 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
   if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
     // Implicit instantiation of function templates and member functions of
     // class templates.
-    if (!Function->getBody()) {
-      // FIXME: distinguish between implicit instantiations of function
-      // templates and explicit specializations (the latter don't get
-      // instantiated, naturally).
-      if (Function->getInstantiatedFromMemberFunction() ||
-          Function->getPrimaryTemplate())
-        PendingImplicitInstantiations.push_back(std::make_pair(Function, Loc));
-    }
-
+    if (!Function->getBody() && 
+        Function->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
+      PendingImplicitInstantiations.push_back(std::make_pair(Function, Loc));
 
     // FIXME: keep track of references to static functions
     Function->setUsed(true);
index 553d62c9e5e8a1d34919ed5a1939af2f22d1aa4d..413d0b949d8ef478469bdb17bd75c3aef9dbe914 100644 (file)
@@ -98,6 +98,12 @@ void test_spec(N0::X0<void*> xvp, void *vp) {
 
 namespace N0 {
   template<> void X0<volatile void>::f1(void *) { } // expected-error{{no function template matches}}
+
+  template<> void X0<const volatile void*>::f1(const volatile void*);
+}
+
+void test_x0_cvvoid(N0::X0<const volatile void*> x0, const volatile void *cvp) {
+  x0.f1(cvp); // okay: we've explicitly specialized
 }
 
 #if 0