[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:18:13 PDT 2023
https://github.com/zmodem created https://github.com/llvm/llvm-project/pull/65961:
…stantiation members during explicit instantiation.
This is a continuation of https://reviews.llvm.org/D155713
Fixes https://github.com/llvm/llvm-project/issues/40363
>From 4649e122e5c100c5fb242cd0e76ef87b9271af0a Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at chromium.org>
Date: Mon, 11 Sep 2023 14:02:40 +0200
Subject: [PATCH] [clang] Don't inherit dllimport/dllexport to
exclude_from_explicit_instantiation members
during explicit instantiation.
Fixes https://github.com/llvm/llvm-project/issues/40363
---
clang/lib/Sema/SemaDeclCXX.cpp | 7 +++
..._from_explicit_instantiation.dllimport.cpp | 48 +++++++++++++++++++
..._from_explicit_instantiation.dllimport.cpp | 27 +++++++++++
3 files changed, 82 insertions(+)
create mode 100644 clang/test/CodeGenCXX/attr-exclude_from_explicit_instantiation.dllimport.cpp
create mode 100644 clang/test/SemaCXX/attr-exclude_from_explicit_instantiation.dllimport.cpp
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