From 853e0aa424e40b80d0bda1dd8a3471a361048e4b Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 4 Feb 2022 11:11:11 +0100 Subject: [PATCH] Don't dllexport reference temporaries Even if the reference itself is dllexport, the temporary should not be. In fact, we're already giving it internal linkage, so dllexporting it is not just wasteful, but will fail to link, as in the example below: $ cat /tmp/a.cc void _DllMainCRTStartup() {} const int __declspec(dllexport) &foo = 42; $ clang-cl -fuse-ld=lld /tmp/a.cc /Zl /link /dll /out:a.dll lld-link: error: : undefined symbol: int const &foo::$RT1 Differential revision: https://reviews.llvm.org/D118980 --- clang/lib/CodeGen/CodeGenModule.cpp | 3 +++ clang/test/CodeGenCXX/reference-temporary-ms.cpp | 8 ++++++++ 2 files changed, 11 insertions(+) create mode 100644 clang/test/CodeGenCXX/reference-temporary-ms.cpp diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 2346176..5ffb954 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -5725,6 +5725,9 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary( /*InsertBefore=*/nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS); if (emitter) emitter->finalize(GV); setGVProperties(GV, VD); + if (GV->getDLLStorageClass() == llvm::GlobalVariable::DLLExportStorageClass) + // The reference temporary should never be dllexport. + GV->setDLLStorageClass(llvm::GlobalVariable::DefaultStorageClass); GV->setAlignment(Align.getAsAlign()); if (supportsCOMDAT() && GV->isWeakForLinker()) GV->setComdat(TheModule.getOrInsertComdat(GV->getName())); diff --git a/clang/test/CodeGenCXX/reference-temporary-ms.cpp b/clang/test/CodeGenCXX/reference-temporary-ms.cpp new file mode 100644 index 0000000..dd12ad8 --- /dev/null +++ b/clang/test/CodeGenCXX/reference-temporary-ms.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -fms-extensions | FileCheck %s + +const int __declspec(dllexport) &Exported = 42; + +// The reference temporary shouldn't be dllexport, even if the reference is. +// CHECK: @"?$RT1@Exported@@3ABHB" = internal constant i32 42 + +// CHECK: @"?Exported@@3ABHB" = dso_local dllexport constant i32* @"?$RT1@Exported@@3ABHB" -- 2.7.4