Author: rnk Date: Thu May 10 18:26:11 2018 New Revision: 332074 URL: http://llvm.org/viewvc/llvm-project?rev=332074&view=rev Log: Don't propagate dllimport to base class template static data members
MSVC doesn't, so we shouldn't. Fixes PR37232. Added: cfe/trunk/test/CodeGenCXX/dllimport-template-sdm.cpp Modified: cfe/trunk/include/clang/Basic/Attr.td cfe/trunk/lib/Sema/SemaDeclCXX.cpp Modified: cfe/trunk/include/clang/Basic/Attr.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=332074&r1=332073&r2=332074&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/Attr.td (original) +++ cfe/trunk/include/clang/Basic/Attr.td Thu May 10 18:26:11 2018 @@ -2566,6 +2566,16 @@ def DLLImport : InheritableAttr, TargetS let Spellings = [Declspec<"dllimport">, GCC<"dllimport">]; let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>; let Documentation = [DLLImportDocs]; + + + let AdditionalMembers = [{ +private: + bool PropagatedToBaseTemplate = false; + +public: + void setPropagatedToBaseTemplate() { PropagatedToBaseTemplate = true; } + bool wasPropagatedToBaseTemplate() { return PropagatedToBaseTemplate; } + }]; } def SelectAny : InheritableAttr { Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=332074&r1=332073&r2=332074&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu May 10 18:26:11 2018 @@ -5626,6 +5626,13 @@ void Sema::checkClassLevelDLLAttribute(C // The class is either imported or exported. const bool ClassExported = ClassAttr->getKind() == attr::DLLExport; + // Check if this was a dllimport attribute propagated from a derived class to + // a base class template specialization. We don't apply these attributes to + // static data members. + const bool PropagatedImport = + !ClassExported && + cast<DLLImportAttr>(ClassAttr)->wasPropagatedToBaseTemplate(); + TemplateSpecializationKind TSK = Class->getTemplateSpecializationKind(); // Ignore explicit dllexport on explicit class template instantiation declarations. @@ -5677,6 +5684,11 @@ void Sema::checkClassLevelDLLAttribute(C } } + // Don't apply dllimport attributes to static data members of class template + // instantiations when the attribute is propagated from a derived class. + if (VD && PropagatedImport) + continue; + if (!cast<NamedDecl>(Member)->isExternallyVisible()) continue; @@ -5729,6 +5741,11 @@ void Sema::propagateDLLAttrToBaseClassTe NewAttr->setInherited(true); BaseTemplateSpec->addAttr(NewAttr); + // If this was an import, mark that we propagated it from a derived class to + // a base class template specialization. + if (auto *ImportAttr = dyn_cast<DLLImportAttr>(NewAttr)) + ImportAttr->setPropagatedToBaseTemplate(); + // If the template is already instantiated, checkDLLAttributeRedeclaration() // needs to be run again to work see the new attribute. Otherwise this will // get run whenever the template is instantiated. Added: cfe/trunk/test/CodeGenCXX/dllimport-template-sdm.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllimport-template-sdm.cpp?rev=332074&view=auto ============================================================================== --- cfe/trunk/test/CodeGenCXX/dllimport-template-sdm.cpp (added) +++ cfe/trunk/test/CodeGenCXX/dllimport-template-sdm.cpp Thu May 10 18:26:11 2018 @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++14 -fms-extensions -o - %s | FileCheck %s --check-prefix=IMPORT +// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++14 -fms-extensions -o - %s -DTEST_EXPORT | FileCheck %s --check-prefix=EXPORT + +#ifndef TEST_EXPORT +#define DLLATTR __declspec(dllimport) +#else +#define DLLATTR __declspec(dllexport) +#endif + +// PR37232: When a dllimport attribute is propagated from a derived class to a +// base class that happens to be a template specialization, it is only applied +// to template *methods*, and not static data members. If a dllexport attribute +// is propagated, it still applies to static data members. + +// IMPORT-DAG: @"?sdm@Exporter@@2HB" = available_externally dllimport constant i32 2, align 4 +// IMPORT-DAG: @"?csdm@?$A@H@@2HB" = linkonce_odr dso_local constant i32 2, comdat, align 4 +// IMPORT-DAG: @"?sdm@?$A@H@@2HA" = linkonce_odr dso_local global i32 1, comdat, align 4 +// IMPORT-DAG: @"?sdm@?$B@H@@2HB" = available_externally dllimport constant i32 2, align 4 +// IMPORT-DAG: @"?sdm@?$C@H@@2HB" = available_externally dllimport constant i32 2, align 4 + +// EXPORT-DAG: @"?sdm@Exporter@@2HB" = weak_odr dso_local dllexport constant i32 2, comdat, align 4 +// EXPORT-DAG: @"?csdm@?$A@H@@2HB" = weak_odr dso_local dllexport constant i32 2, comdat, align 4 +// EXPORT-DAG: @"?sdm@?$A@H@@2HA" = weak_odr dso_local dllexport global i32 1, comdat, align 4 +// EXPORT-DAG: @"?sdm@?$B@H@@2HB" = weak_odr dso_local dllexport constant i32 2, comdat, align 4 +// EXPORT-DAG: @"?sdm@?$C@H@@2HB" = weak_odr dso_local dllexport constant i32 2, comdat, align 4 + + +template <typename T> struct A { + static constexpr int csdm = 2; + static int sdm; +}; +template <typename T> int A<T>::sdm = 1; + +struct DLLATTR Exporter : A<int> { + static constexpr int sdm = 2; +}; + +template <typename T> struct DLLATTR B { static constexpr int sdm = 2; }; + +template <typename T> struct DLLATTR C; +template <typename T> struct C { static constexpr int sdm = 2; }; + +void takeRef(const int &_Args) {} + +int main() { + takeRef(Exporter::sdm); + takeRef(A<int>::csdm); + takeRef(A<int>::sdm); + takeRef(B<int>::sdm); + takeRef(C<int>::sdm); + + return 1; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits