[clang] [clang] Don't inherit dllimport/dllexport to exclude_from_explicit_in… (PR #65961)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 11 06:19:22 PDT 2023
llvmbot wrote:
@llvm/pr-subscribers-clang
<details>
<summary>Changes</summary>
…stantiation members during explicit instantiation.
This is a continuation of https://reviews.llvm.org/D155713
Fixes https://github.com/llvm/llvm-project/issues/40363
--
Full diff: https://github.com/llvm/llvm-project/pull/65961.diff
3 Files Affected:
- (modified) clang/lib/Sema/SemaDeclCXX.cpp (+7)
- (added) clang/test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dllimport.cpp (+48)
- (added) clang/test/SemaCXX/attr-exclude_from_explicit_instantiation.dllimport.cpp (+27)
<pre>
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>;
</pre>
</details>
https://github.com/llvm/llvm-project/pull/65961
More information about the cfe-commits
mailing list