>From 50b541f43089647f09fc96dd59d5b41695ef66ba Mon Sep 17 00:00:00 2001
From: Nico Rieck <[email protected]>
Date: Wed, 28 May 2014 03:53:52 +0200
Subject: Sema: Functions with dll attributes cannot be deleted
---
include/clang/Basic/DiagnosticSemaKinds.td | 2 ++
lib/Sema/SemaDeclCXX.cpp | 6 ++++++
test/SemaCXX/dllexport.cpp | 16 ++++++++++++++++
test/SemaCXX/dllimport.cpp | 19 +++++++++++++++++++
4 files changed, 43 insertions(+)
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 2939e65..50d17f6 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2093,6 +2093,8 @@ def err_attribute_dll_redeclaration : Error<
"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<
+ "attempt to delete %q0 function">;
def err_attribute_dllimport_data_definition : Error<
"definition of dllimport data">;
def err_attribute_dllimport_static_field_definition : Error<
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 2f9f982..6d418da 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -11972,6 +11972,12 @@ void Sema::SetDeclDeleted(Decl *Dcl, SourceLocation DelLoc) {
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;
diff --git a/test/SemaCXX/dllexport.cpp b/test/SemaCXX/dllexport.cpp
index 510d34b..49d9fb2 100644
--- a/test/SemaCXX/dllexport.cpp
+++ b/test/SemaCXX/dllexport.cpp
@@ -212,6 +212,10 @@ __declspec(dllexport) Internal internalRetFunc(); // expected-error{{'internalRe
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{{attempt to delete 'dllexport' function}}
+__declspec(dllexport) inline void deletedInlineFunc() = delete; // expected-error{{attempt to delete 'dllexport' function}}
+
//===----------------------------------------------------------------------===//
@@ -474,6 +478,18 @@ void ExportAlloc::operator delete(void* p) { free(p); }
void ExportAlloc::operator delete[](void* p) { free(p); }
+// Export deleted member functions.
+struct ExportDeleted {
+ __declspec(dllexport) ExportDeleted() = delete; // expected-error{{attempt to delete 'dllexport' function}}
+ __declspec(dllexport) ~ExportDeleted() = delete; // expected-error{{attempt to delete 'dllexport' function}}
+ __declspec(dllexport) ExportDeleted(const ExportDeleted&) = delete; // expected-error{{attempt to delete 'dllexport' function}}
+ __declspec(dllexport) ExportDeleted& operator=(const ExportDeleted&) = delete; // expected-error{{attempt to delete 'dllexport' function}}
+ __declspec(dllexport) ExportDeleted(ExportDeleted&&) = delete; // expected-error{{attempt to delete 'dllexport' function}}
+ __declspec(dllexport) ExportDeleted& operator=(ExportDeleted&&) = delete; // expected-error{{attempt to delete 'dllexport' function}}
+ __declspec(dllexport) void deleted() = delete; // expected-error{{attempt to delete 'dllexport' function}}
+};
+
+
// Export defaulted member functions.
struct ExportDefaulted {
__declspec(dllexport) ExportDefaulted() = default;
diff --git a/test/SemaCXX/dllimport.cpp b/test/SemaCXX/dllimport.cpp
index 2f7cbc8..75123e6 100644
--- a/test/SemaCXX/dllimport.cpp
+++ b/test/SemaCXX/dllimport.cpp
@@ -252,6 +252,13 @@ __declspec(dllimport) Internal internalRetFunc(); // expected-error{{'internalRe
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{{attempt to delete 'dllimport' function}} expected-error{{dllimport cannot be applied to non-inline function definition}}
+__declspec(dllimport) inline void deletedInlineFunc() = delete; // expected-error{{attempt to delete 'dllimport' function}}
+
//===----------------------------------------------------------------------===//
@@ -470,6 +477,18 @@ struct ImportSpecials {
};
+// Import deleted member functions.
+struct ImportDeleted {
+ __declspec(dllimport) ImportDeleted() = delete; // expected-error{{attempt to delete 'dllimport' function}}
+ __declspec(dllimport) ~ImportDeleted() = delete; // expected-error{{attempt to delete 'dllimport' function}}
+ __declspec(dllimport) ImportDeleted(const ImportDeleted&) = delete; // expected-error{{attempt to delete 'dllimport' function}}
+ __declspec(dllimport) ImportDeleted& operator=(const ImportDeleted&) = delete; // expected-error{{attempt to delete 'dllimport' function}}
+ __declspec(dllimport) ImportDeleted(ImportDeleted&&) = delete; // expected-error{{attempt to delete 'dllimport' function}}
+ __declspec(dllimport) ImportDeleted& operator=(ImportDeleted&&) = delete; // expected-error{{attempt to delete 'dllimport' function}}
+ __declspec(dllimport) void deleted() = delete; // expected-error{{attempt to delete 'dllimport' function}}
+};
+
+
// Import allocation functions.
struct ImportAlloc {
__declspec(dllimport) void* operator new(__SIZE_TYPE__);
--
1.9.0.msysgit.0
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits