Sema: Functions with dll attributes cannot be deleted
llvm-svn: 209827
This commit is contained in:
parent
b4662c3e5a
commit
9de0a57687
|
@ -2100,6 +2100,8 @@ def err_attribute_dll_redeclaration : Error<
|
||||||
"redeclaration of %q0 cannot add %q1 attribute">;
|
"redeclaration of %q0 cannot add %q1 attribute">;
|
||||||
def err_attribute_dllimport_function_definition : Error<
|
def err_attribute_dllimport_function_definition : Error<
|
||||||
"dllimport cannot be applied to non-inline function definition">;
|
"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<
|
def err_attribute_dllimport_data_definition : Error<
|
||||||
"definition of dllimport data">;
|
"definition of dllimport data">;
|
||||||
def err_attribute_dllimport_static_field_definition : Error<
|
def err_attribute_dllimport_static_field_definition : Error<
|
||||||
|
|
|
@ -4348,6 +4348,15 @@ static void CheckAbstractClassUsage(AbstractUsageInfo &Info,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \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
|
/// \brief Perform semantic checks on a class definition that has been
|
||||||
/// completing, introducing implicitly-declared members, checking for
|
/// completing, introducing implicitly-declared members, checking for
|
||||||
/// abstract types, etc.
|
/// abstract types, etc.
|
||||||
|
@ -11971,6 +11980,12 @@ void Sema::SetDeclDeleted(Decl *Dcl, SourceLocation DelLoc) {
|
||||||
Fn = Fn->getCanonicalDecl();
|
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())
|
if (Fn->isDeleted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -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 { __declspec(dllexport) void internalFunc() {} } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllexport'}}
|
||||||
namespace ns { __declspec(dllexport) void externalFunc() {} }
|
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* p) { free(p); }
|
||||||
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{{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.
|
// Export defaulted member functions.
|
||||||
struct ExportDefaulted {
|
struct ExportDefaulted {
|
||||||
__declspec(dllexport) ExportDefaulted() = default;
|
__declspec(dllexport) ExportDefaulted() = default;
|
||||||
|
|
|
@ -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 { __declspec(dllimport) void internalFunc(); } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllimport'}}
|
||||||
namespace ns { __declspec(dllimport) void externalFunc(); }
|
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.
|
// Import allocation functions.
|
||||||
struct ImportAlloc {
|
struct ImportAlloc {
|
||||||
__declspec(dllimport) void* operator new(__SIZE_TYPE__);
|
__declspec(dllimport) void* operator new(__SIZE_TYPE__);
|
||||||
|
|
Loading…
Reference in New Issue