Skip to content

Commit 1dacdbe

Browse files
authored
[Clang] Export inline move constructors in dllexport-ed template instantiations on non-MSVC targets (#168170)
Previously, even when MSVC compatibility was not requested, inline move constructors in dllexport-ed templates were not exported, which was seemingly unintended. On non-MSVC targets (MinGW, Cygwin, and PS), such move constructors should be exported consistently with copy constructors and with the behavior of modern MSVC.
1 parent 0aa8b82 commit 1dacdbe

File tree

5 files changed

+27
-4
lines changed

5 files changed

+27
-4
lines changed

clang/include/clang/Basic/LangOptions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,8 @@ class LangOptions : public LangOptionsBase {
623623
!ObjCSubscriptingLegacyRuntime;
624624
}
625625

626+
bool isCompatibleWithMSVC() const { return MSCompatibilityVersion > 0; }
627+
626628
bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const {
627629
return MSCompatibilityVersion >= MajorVersion * 100000U;
628630
}

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6627,6 +6627,7 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) {
66276627
auto *Ctor = dyn_cast<CXXConstructorDecl>(MD);
66286628
if ((MD->isMoveAssignmentOperator() ||
66296629
(Ctor && Ctor->isMoveConstructor())) &&
6630+
getLangOpts().isCompatibleWithMSVC() &&
66306631
!getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015))
66316632
continue;
66326633

clang/test/CodeGenCXX/dllexport.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,5 +1130,6 @@ class __declspec(dllexport) ACE_Shared_Object {
11301130
class __declspec(dllexport) ACE_Service_Object : public ACE_Shared_Object {};
11311131
// Implicit move constructor declaration.
11321132
// MSVC2015-DAG: define weak_odr dso_local dllexport {{.+}}ACE_Service_Object@@Q{{.+}}@$$Q
1133+
// PS-DAG: define weak_odr dllexport void @_ZN18ACE_Service_ObjectC1EOS_
11331134
// The declarations should not be exported.
11341135
// MSVC2013-NOT: define weak_odr dso_local dllexport {{.+}}ACE_Service_Object@@Q{{.+}}@$$Q

clang/test/CodeGenCXX/dllimport.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ struct ExplicitSpec_NotImported {};
3535
#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
3636
#define USESTATICMEMFUNC(class, func) void (*UNIQ(use)())() { return &class::func; }
3737
#define USECLASS(class) void UNIQ(USE)() { class x; }
38-
#define USECOPYASSIGN(class) class& (class::*UNIQ(use)())(class&) { return &class::operator=; }
38+
#define USECOPYASSIGN(class) class& (class::*UNIQ(use)())(const class&) { return &class::operator=; }
3939
#define USEMOVEASSIGN(class) class& (class::*UNIQ(use)())(class&&) { return &class::operator=; }
4040

4141
//===----------------------------------------------------------------------===//
@@ -649,13 +649,15 @@ struct __declspec(dllimport) T {
649649
static int b;
650650
// MO1-DAG: @"?b@T@@2HA" = external dllimport global i32
651651

652-
T& operator=(T&) = default;
653-
// MO1-DAG: define available_externally dllimport x86_thiscallcc nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @"??4T@@QAEAAU0@AAU0@@Z"
652+
T& operator=(const T&) = default;
653+
// MO1-DAG: define available_externally dllimport x86_thiscallcc nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @"??4T@@QAEAAU0@ABU0@@Z"
654+
// PS-DAG: declare dllimport nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @_ZN1TaSERKS_
654655

655656
T& operator=(T&&) = default;
656-
// Note: Don't mark inline move operators dllimport because current MSVC versions don't export them.
657+
// Note: Don't mark inline move operators dllimport because MSVC versions before 2015 don't export them.
657658
// M18-DAG: define linkonce_odr dso_local x86_thiscallcc nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @"??4T@@QAEAAU0@$$QAU0@@Z"
658659
// M19-DAG: define available_externally dllimport x86_thiscallcc nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @"??4T@@QAEAAU0@$$QAU0@@Z"
660+
// PS-DAG: declare dllimport nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @_ZN1TaSEOS_
659661
};
660662
USEMEMFUNC(T, a)
661663
USESTATICMEMFUNC(T, StaticMethod)

clang/test/CodeGenCXX/mingw-template-dllexport.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,16 @@
1010

1111
template <class T>
1212
class c {
13+
public:
14+
c(const c &) {}
15+
c(c &&) noexcept {}
1316
void f() {}
1417
};
1518

1619
template class __declspec(dllexport) c<int>;
1720

21+
// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiEC1ERKS0_
22+
// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiEC1EOS0_
1823
// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiE1fEv
1924

2025
extern template class __declspec(dllexport) c<char>;
@@ -27,6 +32,18 @@ template class __declspec(dllexport) c<double>;
2732

2833
// CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN1cIdE1fEv
2934

35+
extern template class __declspec(dllimport) c<short>;
36+
37+
// CHECK: declare dllimport {{.*}} @_ZN1cIsEC1ERKS0_
38+
// CHECK: declare dllimport {{.*}} @_ZN1cIsEC1EOS0_
39+
// CHECK: declare dllimport {{.*}} @_ZN1cIsE1fEv
40+
41+
void use_ctors(c<short> &&x) {
42+
c<short> y{x};
43+
c<short> z{static_cast<c<short> &&>(x)};
44+
z.f();
45+
}
46+
3047
template <class T>
3148
struct outer {
3249
void f();

0 commit comments

Comments
 (0)