[clang] 84216d1 - [clang] Don't inherit dllimport/dllexport to exclude_from_explicit_instantiation members during explicit instantiation (#65961)

via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 14 01:20:06 PDT 2023


Author: Hans
Date: 2023-09-14T10:20:01+02:00
New Revision: 84216d17359fcf6c314726d9f8d0416f8118d968

URL: https://github.com/llvm/llvm-project/commit/84216d17359fcf6c314726d9f8d0416f8118d968
DIFF: https://github.com/llvm/llvm-project/commit/84216d17359fcf6c314726d9f8d0416f8118d968.diff

LOG: [clang] Don't inherit dllimport/dllexport to exclude_from_explicit_instantiation members during explicit instantiation (#65961)

This is a continuation of https://reviews.llvm.org/D155713

Fixes https://github.com/llvm/llvm-project/issues/40363

Added: 
    clang/test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dllimport.cpp
    clang/test/SemaCXX/attr-exclude_from_explicit_instantiation.dllimport.cpp

Modified: 
    clang/lib/Sema/SemaDeclCXX.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 2b2b7391f88fd54..1f2bb1edd3b7be5 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -6602,6 +6602,13 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) {
     if (!VD && !MD)
       continue;
 
+    if ((TSK == TSK_ExplicitInstantiationDeclaration ||
+         TSK == TSK_ExplicitInstantiationDefinition) &&
+        Member->hasAttr<ExcludeFromExplicitInstantiationAttr>()) {
+      // Skip members excluded from instantiation.
+      continue;
+    }
+
     if (MD) {
       // Don't process deleted methods.
       if (MD->isDeleted())

diff  --git a/clang/test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dllimport.cpp b/clang/test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dllimport.cpp
new file mode 100644
index 000000000000000..b3c804839be1ee4
--- /dev/null
+++ b/clang/test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dllimport.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-windows -fms-extensions -emit-llvm -O0 -o - %s | FileCheck %s
+
+// Test that dllimport and exclude_from_explicit_instantiation work properly
+// together. Specifically, we check that when exclude_from_explicit_instantiation
+// is used on a method, the compiler doesn't expect it to be provided externally
+// even if it is marked with dllimport.
+//
+// https://github.com/llvm/llvm-project/issues/40363
+
+#define DLLIMPORT __declspec(dllimport)
+#define DLLEXPORT __declspec(dllexport)
+#define EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((exclude_from_explicit_instantiation))
+
+template <class T>
+struct DLLIMPORT Foo {
+  EXCLUDE_FROM_EXPLICIT_INSTANTIATION void x() {}
+};
+
+template <class T>
+struct Bar {
+  EXCLUDE_FROM_EXPLICIT_INSTANTIATION void x() {}
+};
+
+extern template struct Foo<int>;
+extern template struct DLLIMPORT Bar<int>;
+
+
+template <class T>
+struct Baz {
+  EXCLUDE_FROM_EXPLICIT_INSTANTIATION void f() {}
+};
+
+template struct DLLEXPORT Baz<int>;
+
+
+void test(Foo<int>& foo, Bar<int>& bar, Baz<int>& baz) {
+  // Not imported.
+  // CHECK-DAG: define linkonce_odr dso_local void @"?x@?$Foo at H@@QEAAXXZ"
+  foo.x();
+
+  // Not imported.
+  // CHECK-DAG: define linkonce_odr dso_local void @"?x@?$Bar at H@@QEAAXXZ"
+  bar.x();
+
+  // Not exported.
+  // CHECK-DAG: define linkonce_odr dso_local void @"?f@?$Baz at H@@QEAAXXZ"
+  baz.f();
+}

diff  --git a/clang/test/SemaCXX/attr-exclude_from_explicit_instantiation.dllimport.cpp b/clang/test/SemaCXX/attr-exclude_from_explicit_instantiation.dllimport.cpp
new file mode 100644
index 000000000000000..bdca2d8895f516c
--- /dev/null
+++ b/clang/test/SemaCXX/attr-exclude_from_explicit_instantiation.dllimport.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-windows -fms-extensions -verify %s
+
+// Test that an entity marked as both dllimport and exclude_from_explicit_instantiation
+// isn't instantiated.
+
+#define DLLIMPORT __declspec(dllimport)
+#define EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((exclude_from_explicit_instantiation))
+
+template <class T>
+struct DLLIMPORT Foo {
+  EXCLUDE_FROM_EXPLICIT_INSTANTIATION void x();
+};
+
+template <class T>
+struct Bar {
+  DLLIMPORT EXCLUDE_FROM_EXPLICIT_INSTANTIATION inline void x();
+};
+
+template <class T>
+void Foo<T>::x() { using Fail = typename T::fail; }
+
+template <class T>
+DLLIMPORT inline void Bar<T>::x() { using Fail = typename T::fail; }
+
+// expected-no-diagnostics
+template struct Foo<int>;
+template struct Bar<int>;


        


More information about the cfe-commits mailing list