r209827 - Sema: Functions with dll attributes cannot be deleted

Nico Rieck nico.rieck at gmail.com
Thu May 29 09:51:19 PDT 2014


Author: nrieck
Date: Thu May 29 11:51:19 2014
New Revision: 209827

URL: http://llvm.org/viewvc/llvm-project?rev=209827&view=rev
Log:
Sema: Functions with dll attributes cannot be deleted

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/SemaCXX/dllexport.cpp
    cfe/trunk/test/SemaCXX/dllimport.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=209827&r1=209826&r2=209827&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu May 29 11:51:19 2014
@@ -2100,6 +2100,8 @@ def err_attribute_dll_redeclaration : Er
   "redeclaration of %q0 cannot add %q1 attribute">;
 def err_attribute_dllimport_function_definition : Error<
   "dllimport cannot be applied to non-inline function definition">;
+def err_attribute_dll_deleted : Error<
+  "attribute %q0 cannot be applied to a deleted function">;
 def err_attribute_dllimport_data_definition : Error<
   "definition of dllimport data">;
 def err_attribute_dllimport_static_field_definition : Error<

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=209827&r1=209826&r2=209827&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu May 29 11:51:19 2014
@@ -4348,6 +4348,15 @@ static void CheckAbstractClassUsage(Abst
   }
 }
 
+/// \brief Return a DLL attribute from the declaration.
+static InheritableAttr *getDLLAttr(Decl *D) {
+  if (auto *Import = D->getAttr<DLLImportAttr>())
+    return Import;
+  if (auto *Export = D->getAttr<DLLExportAttr>())
+    return Export;
+  return nullptr;
+}
+
 /// \brief Perform semantic checks on a class definition that has been
 /// completing, introducing implicitly-declared members, checking for
 /// abstract types, etc.
@@ -11971,6 +11980,12 @@ void Sema::SetDeclDeleted(Decl *Dcl, Sou
     Fn = Fn->getCanonicalDecl();
   }
 
+  // dllimport/dllexport cannot be deleted.
+  if (const InheritableAttr *DLLAttr = getDLLAttr(Fn)) {
+    Diag(Fn->getLocation(), diag::err_attribute_dll_deleted) << DLLAttr;
+    Fn->setInvalidDecl();
+  }
+
   if (Fn->isDeleted())
     return;
 

Modified: cfe/trunk/test/SemaCXX/dllexport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dllexport.cpp?rev=209827&r1=209826&r2=209827&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/dllexport.cpp (original)
+++ cfe/trunk/test/SemaCXX/dllexport.cpp Thu May 29 11:51:19 2014
@@ -212,6 +212,10 @@ __declspec(dllexport) Internal internalR
 namespace    { __declspec(dllexport) void internalFunc() {} } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllexport'}}
 namespace ns { __declspec(dllexport) void externalFunc() {} }
 
+// Export deleted function.
+__declspec(dllexport) void deletedFunc() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+__declspec(dllexport) inline void deletedInlineFunc() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+
 
 
 //===----------------------------------------------------------------------===//
@@ -474,6 +478,18 @@ void ExportAlloc::operator delete(void*
 void ExportAlloc::operator delete[](void* p) { free(p); }
 
 
+// Export deleted member functions.
+struct ExportDeleted {
+  __declspec(dllexport) ExportDeleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+  __declspec(dllexport) ~ExportDeleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+  __declspec(dllexport) ExportDeleted(const ExportDeleted&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+  __declspec(dllexport) ExportDeleted& operator=(const ExportDeleted&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+  __declspec(dllexport) ExportDeleted(ExportDeleted&&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+  __declspec(dllexport) ExportDeleted& operator=(ExportDeleted&&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+  __declspec(dllexport) void deleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+};
+
+
 // Export defaulted member functions.
 struct ExportDefaulted {
   __declspec(dllexport) ExportDefaulted() = default;

Modified: cfe/trunk/test/SemaCXX/dllimport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dllimport.cpp?rev=209827&r1=209826&r2=209827&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/dllimport.cpp (original)
+++ cfe/trunk/test/SemaCXX/dllimport.cpp Thu May 29 11:51:19 2014
@@ -252,6 +252,13 @@ __declspec(dllimport) Internal internalR
 namespace    { __declspec(dllimport) void internalFunc(); } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllimport'}}
 namespace ns { __declspec(dllimport) void externalFunc(); }
 
+// Import deleted functions.
+// FIXME: Deleted functions are definitions so a missing inline is diagnosed
+// here which is irrelevant. But because the delete keyword is parsed later
+// there is currently no straight-forward way to avoid this diagnostic.
+__declspec(dllimport) void deletedFunc() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} expected-error{{dllimport cannot be applied to non-inline function definition}}
+__declspec(dllimport) inline void deletedInlineFunc() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+
 
 
 //===----------------------------------------------------------------------===//
@@ -459,6 +466,18 @@ struct ImportSpecials {
 };
 
 
+// Import deleted member functions.
+struct ImportDeleted {
+  __declspec(dllimport) ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+  __declspec(dllimport) ~ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+  __declspec(dllimport) ImportDeleted(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+  __declspec(dllimport) ImportDeleted& operator=(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+  __declspec(dllimport) ImportDeleted(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+  __declspec(dllimport) ImportDeleted& operator=(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+  __declspec(dllimport) void deleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+};
+
+
 // Import allocation functions.
 struct ImportAlloc {
   __declspec(dllimport) void* operator new(__SIZE_TYPE__);





More information about the cfe-commits mailing list