Skip to content

Conversation

@kikairoya
Copy link
Contributor

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.

…antiations on non-MSVC targets

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.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Nov 15, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 15, 2025

@llvm/pr-subscribers-clang

Author: Tomohiro Kashiwada (kikairoya)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/168170.diff

3 Files Affected:

  • (modified) clang/lib/Sema/SemaDeclCXX.cpp (+1)
  • (modified) clang/test/CodeGenCXX/dllexport.cpp (+1)
  • (modified) clang/test/CodeGenCXX/mingw-template-dllexport.cpp (+2)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index aa36a79142e52..5f741166d0e29 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -6627,6 +6627,7 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) {
         auto *Ctor = dyn_cast<CXXConstructorDecl>(MD);
         if ((MD->isMoveAssignmentOperator() ||
              (Ctor && Ctor->isMoveConstructor())) &&
+            getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2010) &&
             !getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015))
           continue;
 
diff --git a/clang/test/CodeGenCXX/dllexport.cpp b/clang/test/CodeGenCXX/dllexport.cpp
index ef9d8131c511c..a34a87c5b9f21 100644
--- a/clang/test/CodeGenCXX/dllexport.cpp
+++ b/clang/test/CodeGenCXX/dllexport.cpp
@@ -1131,5 +1131,6 @@ class __declspec(dllexport) ACE_Shared_Object {
 class __declspec(dllexport) ACE_Service_Object : public ACE_Shared_Object {};
 // Implicit move constructor declaration.
 // MSVC2015-DAG: define weak_odr dso_local dllexport {{.+}}ACE_Service_Object@@Q{{.+}}@$$Q
+// PS-DAG: define weak_odr dllexport void @_ZN18ACE_Service_ObjectC1EOS_
 // The declarations should not be exported.
 // MSVC2013-NOT: define weak_odr dso_local dllexport {{.+}}ACE_Service_Object@@Q{{.+}}@$$Q
diff --git a/clang/test/CodeGenCXX/mingw-template-dllexport.cpp b/clang/test/CodeGenCXX/mingw-template-dllexport.cpp
index de112d6da53db..15969d2415cca 100644
--- a/clang/test/CodeGenCXX/mingw-template-dllexport.cpp
+++ b/clang/test/CodeGenCXX/mingw-template-dllexport.cpp
@@ -10,11 +10,13 @@
 
 template <class T>
 class c {
+  c(c &&) noexcept {}
   void f() {}
 };
 
 template class __declspec(dllexport) c<int>;
 
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiEC1EOS0_
 // CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiE1fEv
 
 extern template class __declspec(dllexport) c<char>;

@kikairoya
Copy link
Contributor Author

cc: @mstorsjo @jmorse

@jmorse
Copy link
Member

jmorse commented Nov 19, 2025

@bd1976bris @playstation-edd this feels harmless to me (exporting inline move-constructors and move-operators where we already do it for normal copy ones?) , however I'm no expert on dllexport and friends. Opinions please!

@bd1976bris
Copy link
Collaborator

bd1976bris commented Nov 26, 2025

Apologies for the slow reply here. I'll try to take a look tomorrow (GMT).

auto *Ctor = dyn_cast<CXXConstructorDecl>(MD);
if ((MD->isMoveAssignmentOperator() ||
(Ctor && Ctor->isMoveConstructor())) &&
getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2010) &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tripped me up when I first looked at it. I think it would be nice to introduce a no argument form bool isCompatibleWithMSVC() const; and then write the MSVC compatibility bit as: getLangOpts().isCompatibleWithMSVC() && !getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015)

Copy link
Collaborator

@bd1976bris bd1976bris left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking at this. I agree the current behaviour looks unintended.

I left a suggestion for improving the readability of the change. It would also be good to see dllimport test cases added.

Functionally this change looks good to me and I don't think that it poses an ABI problem for PlayStation except perhaps for internal codebases. Any such cases should be discovered via our release testing and we can deal with those as they arise.

I can't see any good reason why this change wouldn't be acceptable for other affected targets e.g. MinGW.

I suggest we get this in as quickly as possible to give affected targets as long as possible to exercise this change before the next release.

@bd1976bris bd1976bris requested a review from mstorsjo November 26, 2025 22:18
@kikairoya
Copy link
Contributor Author

Thank you for the reviewing.
I've added a new function isCompatibleWithMSVC and tests for dllimport.

Copy link
Collaborator

@bd1976bris bd1976bris left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM. Maybe wait until Friday to merge this to give a bit more time for @mstorsjo to comment.

@mstorsjo
Copy link
Member

Thanks, LGTM. Maybe wait until Friday to merge this to give a bit more time for @mstorsjo to comment.

No objection from me to this; I can't say I can confidently review this as such, but it sounds reasonable.

@kikairoya
Copy link
Contributor Author

If it's OK to merge this, could you please merge this for me? I don't have the permission.

@jmorse
Copy link
Member

jmorse commented Dec 9, 2025

With @bd1976bris having approved, without objection I'll click merge today or tomorrow.

@jmorse jmorse merged commit 1dacdbe into llvm:main Dec 9, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants