r210141 - Downgrade "definition of dllimport static field" error to warning for class templates (PR19902)
Hans Wennborg
hans at hanshq.net
Tue Jun 3 17:18:42 PDT 2014
Author: hans
Date: Tue Jun 3 19:18:41 2014
New Revision: 210141
URL: http://llvm.org/viewvc/llvm-project?rev=210141&view=rev
Log:
Downgrade "definition of dllimport static field" error to warning for class templates (PR19902)
This allows us to compile the following kind of code, which occurs in MSVC
headers:
template <typename> struct S {
__declspec(dllimport) static int x;
};
template <typename T> int S<T>::x;
The definition works similarly to a dllimport inline function definition and
gets available_externally linkage.
Differential Revision: http://reviews.llvm.org/D3998
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/CodeGenCXX/dllimport.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=210141&r1=210140&r2=210141&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jun 3 19:18:41 2014
@@ -2109,6 +2109,9 @@ def err_attribute_dllimport_data_definit
"definition of dllimport data">;
def err_attribute_dllimport_static_field_definition : Error<
"definition of dllimport static field not allowed">;
+def warn_attribute_dllimport_static_field_definition : Warning<
+ "definition of dllimport static field">,
+ InGroup<DiagGroup<"dllimport-static-field-def">>;
def err_attribute_dll_member_of_dll_class : Error<
"attribute %q0 cannot be applied to member of %q1 class">;
def err_attribute_weakref_not_static : Error<
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=210141&r1=210140&r2=210141&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Jun 3 19:18:41 2014
@@ -9061,10 +9061,19 @@ Sema::FinalizeDeclaration(Decl *ThisDecl
if (const DLLImportAttr *IA = VD->getAttr<DLLImportAttr>()) {
if (VD->isStaticDataMember() && VD->isOutOfLine() &&
VD->isThisDeclarationADefinition()) {
+ // We allow definitions of dllimport class template static data members
+ // with a warning.
+ bool IsClassTemplateMember =
+ cast<CXXRecordDecl>(VD->getFirstDecl()->getDeclContext())
+ ->getDescribedClassTemplate();
+
Diag(VD->getLocation(),
- diag::err_attribute_dllimport_static_field_definition);
+ IsClassTemplateMember
+ ? diag::warn_attribute_dllimport_static_field_definition
+ : diag::err_attribute_dllimport_static_field_definition);
Diag(IA->getLocation(), diag::note_attribute);
- VD->setInvalidDecl();
+ if (!IsClassTemplateMember)
+ VD->setInvalidDecl();
}
}
Modified: cfe/trunk/test/CodeGenCXX/dllimport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllimport.cpp?rev=210141&r1=210140&r2=210141&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/dllimport.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/dllimport.cpp Tue Jun 3 19:18:41 2014
@@ -571,6 +571,15 @@ namespace Vtordisp {
template class C<char>;
}
+namespace ClassTemplateStaticDef {
+ template <typename T> struct __declspec(dllimport) S {
+ static int x;
+ };
+ template <typename T> int S<T>::x;
+ // CHECK-DAG: @"\01?x@?$S at H@ClassTemplateStaticDef@@2HA" = available_externally dllimport global i32 0
+ int f() { return S<int>::x; }
+}
+
//===----------------------------------------------------------------------===//
// Negative checks
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/test/SemaCXX/dllimport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dllimport.cpp?rev=210141&r1=210140&r2=210141&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/dllimport.cpp (original)
+++ cfe/trunk/test/SemaCXX/dllimport.cpp Tue Jun 3 19:18:41 2014
@@ -816,9 +816,9 @@ template<typename T> void ImportC
template<typename T> inline void ImportClassTmplMembers<T>::staticInlineDef() {}
template<typename T> void ImportClassTmplMembers<T>::staticInlineDecl() {}
-template<typename T> int ImportClassTmplMembers<T>::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}
-template<typename T> const int ImportClassTmplMembers<T>::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}
-template<typename T> constexpr int ImportClassTmplMembers<T>::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}}
+template<typename T> int ImportClassTmplMembers<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}
+template<typename T> const int ImportClassTmplMembers<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}}
+template<typename T> constexpr int ImportClassTmplMembers<T>::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}}
// Redeclarations cannot add dllimport.
@@ -853,13 +853,13 @@ template<typename T> __declspec(dllimpor
template<typename T> __declspec(dllimport) void CTMR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllimport' attribute}}
template<typename T> __declspec(dllimport) int CTMR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllimport' attribute}}
- // expected-error at -1{{definition of dllimport static field not allowed}}
+ // expected-warning at -1{{definition of dllimport static field}}
// expected-note at -2{{attribute is here}}
template<typename T> __declspec(dllimport) const int CTMR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllimport' attribute}}
- // expected-error at -1{{definition of dllimport static field not allowed}}
+ // expected-warning at -1{{definition of dllimport static field}}
// expected-note at -2{{attribute is here}}
template<typename T> __declspec(dllimport) constexpr int CTMR<T>::ConstexprField; // expected-error{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllimport' attribute}}
- // expected-error at -1{{definition of dllimport static field not allowed}}
+ // expected-warning at -1{{definition of dllimport static field}}
// expected-note at -2{{attribute is here}}
@@ -901,9 +901,9 @@ template<typename T> template<typename U
template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::staticInlineDecl() {}
#if __has_feature(cxx_variable_templates)
-template<typename T> template<typename U> int ImportClsTmplMemTmpl<T>::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}
-template<typename T> template<typename U> const int ImportClsTmplMemTmpl<T>::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}
-template<typename T> template<typename U> constexpr int ImportClsTmplMemTmpl<T>::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}}
+template<typename T> template<typename U> int ImportClsTmplMemTmpl<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}
+template<typename T> template<typename U> const int ImportClsTmplMemTmpl<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}}
+template<typename T> template<typename U> constexpr int ImportClsTmplMemTmpl<T>::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}}
#endif // __has_feature(cxx_variable_templates)
@@ -935,13 +935,13 @@ template<typename T> template<typename U
#if __has_feature(cxx_variable_templates)
template<typename T> template<typename U> __declspec(dllimport) int CTMTR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllimport' attribute}}
- // expected-error at -1{{definition of dllimport static field not allowed}}
+ // expected-warning at -1{{definition of dllimport static field}}
// expected-note at -2{{attribute is here}}
template<typename T> template<typename U> __declspec(dllimport) const int CTMTR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllimport' attribute}}
- // expected-error at -1{{definition of dllimport static field not allowed}}
+ // expected-warning at -1{{definition of dllimport static field}}
// expected-note at -2{{attribute is here}}
template<typename T> template<typename U> __declspec(dllimport) constexpr int CTMTR<T>::ConstexprField; // expected-error{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllimport' attribute}}
- // expected-error at -1{{definition of dllimport static field not allowed}}
+ // expected-warning at -1{{definition of dllimport static field}}
// expected-note at -2{{attribute is here}}
#endif // __has_feature(cxx_variable_templates)
@@ -976,3 +976,10 @@ class __declspec(dllexport) ExportClassW
void __declspec(dllimport) foo();
void __declspec(dllexport) bar();
};
+
+namespace ImportedExplicitSpecialization {
+template <typename T> struct S { static int x; };
+template <typename T> int S<T>::x = sizeof(T);
+template <> struct __declspec(dllimport) S<int> { static int x; }; // expected-note{{attribute is here}}
+int S<int>::x = -1; // expected-error{{definition of dllimport static field not allowed}}
+}
More information about the cfe-commits
mailing list