Skip to content

Commit d230adc

Browse files
committed
[clang] Fix loss of dllexport for exported template specialization
When dropping DLL attributes, ensure that the most recent declaration is being checked.
1 parent 4b1fef6 commit d230adc

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4512,6 +4512,19 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) {
45124512
return Resolver;
45134513
}
45144514

4515+
bool CodeGenModule::shouldDropDLLAttribute(const Decl *D,
4516+
const llvm::GlobalValue *GV) const {
4517+
auto SC = GV->getDLLStorageClass();
4518+
if (SC == llvm::GlobalValue::DefaultStorageClass)
4519+
return false;
4520+
const Decl *MRD = D->getMostRecentDecl();
4521+
return (((SC == llvm::GlobalValue::DLLImportStorageClass &&
4522+
!MRD->hasAttr<DLLImportAttr>()) ||
4523+
(SC == llvm::GlobalValue::DLLExportStorageClass &&
4524+
!MRD->hasAttr<DLLExportAttr>())) &&
4525+
!shouldMapVisibilityToDLLExport(cast<NamedDecl>(MRD)));
4526+
}
4527+
45154528
/// GetOrCreateLLVMFunction - If the specified mangled name is not in the
45164529
/// module, create and return an llvm Function with the specified type. If there
45174530
/// is something in the module with the specified name, return it potentially
@@ -4564,8 +4577,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(
45644577
}
45654578

45664579
// Handle dropped DLL attributes.
4567-
if (D && !D->hasAttr<DLLImportAttr>() && !D->hasAttr<DLLExportAttr>() &&
4568-
!shouldMapVisibilityToDLLExport(cast_or_null<NamedDecl>(D))) {
4580+
if (D && shouldDropDLLAttribute(D, Entry)) {
45694581
Entry->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
45704582
setDSOLocal(Entry);
45714583
}
@@ -4859,8 +4871,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty,
48594871
}
48604872

48614873
// Handle dropped DLL attributes.
4862-
if (D && !D->hasAttr<DLLImportAttr>() && !D->hasAttr<DLLExportAttr>() &&
4863-
!shouldMapVisibilityToDLLExport(D))
4874+
if (D && shouldDropDLLAttribute(D, Entry))
48644875
Entry->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
48654876

48664877
if (LangOpts.OpenMP && !LangOpts.OpenMPSimd && D)

clang/lib/CodeGen/CodeGenModule.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,6 +1594,8 @@ class CodeGenModule : public CodeGenTypeCache {
15941594
}
15951595

15961596
private:
1597+
bool shouldDropDLLAttribute(const Decl *D, const llvm::GlobalValue *GV) const;
1598+
15971599
llvm::Constant *GetOrCreateLLVMFunction(
15981600
StringRef MangledName, llvm::Type *Ty, GlobalDecl D, bool ForVTable,
15991601
bool DontDefer = false, bool IsThunk = false,
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %clang_cc1 -triple i686-windows -fdeclspec -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-MS
2+
// RUN: %clang_cc1 -triple i686-windows-itanium -fdeclspec -emit-llvm %s -o - | FileCheck %s
3+
// RUN: %clang_cc1 -triple x86_64-scei-ps4 -fdeclspec -emit-llvm %s -o - | FileCheck %s
4+
// RUN: %clang_cc1 -triple x86_64-sie-ps5 -fdeclspec -emit-llvm %s -o - | FileCheck %s
5+
6+
struct s {
7+
template <bool b = true> static bool f();
8+
};
9+
10+
template <typename T> bool template_using_f(T) { return s::f(); }
11+
12+
bool use_template_using_f() { return template_using_f(0); }
13+
14+
template<>
15+
bool __declspec(dllexport) s::f<true>() { return true; }
16+
17+
// CHECK-MS: dllexport {{.*}} @"??$f@$00@s@@SA_NXZ"
18+
// CHECK: dllexport {{.*}} @_ZN1s1fILb1EEEbv

0 commit comments

Comments
 (0)