Author: dblaikie
Date: Mon Jun 25 16:55:30 2012
New Revision: 159167

URL: http://llvm.org/viewvc/llvm-project?rev=159167&view=rev
Log:
PR12937: Explicitly deleting an explicit template specialization.

This works around a quirk in the way that explicit template specializations are
handled in Clang. We generate an implicit declaration from the original
template which the explicit specialization is considered to redeclare. This
trips up the explicit delete logic.

This change only works around that strange representation. At some point it'd
be nice to remove those extra declarations to make the AST more accurately
reflect the C++ semantics.

Review by Doug Gregor.

Added:
    cfe/trunk/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.delete/
    cfe/trunk/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.delete/p4.cpp
Modified:
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/SemaCXX/deleted-function.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=159167&r1=159166&r2=159167&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Jun 25 16:55:30 2012
@@ -10316,8 +10316,13 @@
     return;
   }
   if (const FunctionDecl *Prev = Fn->getPreviousDecl()) {
-    Diag(DelLoc, diag::err_deleted_decl_not_first);
-    Diag(Prev->getLocation(), diag::note_previous_declaration);
+    // Don't consider the implicit declaration we generate for explicit
+    // specializations. FIXME: Do not generate these implicit declarations.
+    if (Prev->getTemplateSpecializationKind() != TSK_ExplicitSpecialization
+        || Prev->getPreviousDecl()) {
+      Diag(DelLoc, diag::err_deleted_decl_not_first);
+      Diag(Prev->getLocation(), diag::note_previous_declaration);
+    }
     // If the declaration wasn't the first, we delete the function anyway for
     // recovery.
   }

Added: cfe/trunk/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.delete/p4.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.delete/p4.cpp?rev=159167&view=auto
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.delete/p4.cpp (added)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.delete/p4.cpp Mon Jun 
25 16:55:30 2012
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+template<typename> void func();
+template<> void func<int>() = delete;
+
+template<typename> void func2();
+template<> void func2<int>(); // expected-note {{previous declaration is here}}
+template<> void func2<int>() = delete; // expected-error {{deleted definition 
must be first declaration}}

Modified: cfe/trunk/test/SemaCXX/deleted-function.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/deleted-function.cpp?rev=159167&r1=159166&r2=159167&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/deleted-function.cpp (original)
+++ cfe/trunk/test/SemaCXX/deleted-function.cpp Mon Jun 25 16:55:30 2012
@@ -55,3 +55,11 @@
   ~Z() {} // expected-error {{attempt to use a deleted function}}
 };
 DelDtor dd; // expected-error {{attempt to use a deleted function}}
+
+template<typename> void test2() = delete;
+template void test2<int>();
+
+// test3 really shouldn't have behavior that differs from test2 above
+template<typename> void test3() = delete; // expected-note {{explicit 
instantiation refers here}}
+template<typename> void test3();
+template void test3<int>(); // expected-error {{explicit instantiation of 
undefined function template 'test3'}}


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to