From 84216d17359fcf6c314726d9f8d0416f8118d968 Mon Sep 17 00:00:00 2001 From: Hans Date: Thu, 14 Sep 2023 10:20:01 +0200 Subject: [PATCH] [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 --- 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 2b2b7391f88fd5..1f2bb1edd3b7be 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()) { + // 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 00000000000000..b3c804839be1ee --- /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 +struct DLLIMPORT Foo { + EXCLUDE_FROM_EXPLICIT_INSTANTIATION void x() {} +}; + +template +struct Bar { + EXCLUDE_FROM_EXPLICIT_INSTANTIATION void x() {} +}; + +extern template struct Foo; +extern template struct DLLIMPORT Bar; + + +template +struct Baz { + EXCLUDE_FROM_EXPLICIT_INSTANTIATION void f() {} +}; + +template struct DLLEXPORT Baz; + + +void test(Foo& foo, Bar& bar, Baz& baz) { + // Not imported. + // CHECK-DAG: define linkonce_odr dso_local void @"?x@?$Foo@H@@QEAAXXZ" + foo.x(); + + // Not imported. + // CHECK-DAG: define linkonce_odr dso_local void @"?x@?$Bar@H@@QEAAXXZ" + bar.x(); + + // Not exported. + // CHECK-DAG: define linkonce_odr dso_local void @"?f@?$Baz@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 00000000000000..bdca2d8895f516 --- /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 +struct DLLIMPORT Foo { + EXCLUDE_FROM_EXPLICIT_INSTANTIATION void x(); +}; + +template +struct Bar { + DLLIMPORT EXCLUDE_FROM_EXPLICIT_INSTANTIATION inline void x(); +}; + +template +void Foo::x() { using Fail = typename T::fail; } + +template +DLLIMPORT inline void Bar::x() { using Fail = typename T::fail; } + +// expected-no-diagnostics +template struct Foo; +template struct Bar;