mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-03 00:20:40 +03:00
-fvisibility=hidden: Hide init symbols, TypeInfos and vtables too if the associated aggregate isn't exported (#3129)
This commit is contained in:
parent
ceee37dda2
commit
c1725809c2
10 changed files with 85 additions and 16 deletions
|
@ -146,7 +146,7 @@ public:
|
||||||
auto &initZ = ir->getInitSymbol();
|
auto &initZ = ir->getInitSymbol();
|
||||||
auto initGlobal = llvm::cast<LLGlobalVariable>(initZ);
|
auto initGlobal = llvm::cast<LLGlobalVariable>(initZ);
|
||||||
initZ = irs->setGlobalVarInitializer(initGlobal, ir->getDefaultInit());
|
initZ = irs->setGlobalVarInitializer(initGlobal, ir->getDefaultInit());
|
||||||
setLinkage(decl, initGlobal);
|
setLinkageAndVisibility(decl, initGlobal);
|
||||||
|
|
||||||
// emit typeinfo
|
// emit typeinfo
|
||||||
if (!ir->suppressTypeInfo()) {
|
if (!ir->suppressTypeInfo()) {
|
||||||
|
@ -198,7 +198,7 @@ public:
|
||||||
auto &initZ = ir->getInitSymbol();
|
auto &initZ = ir->getInitSymbol();
|
||||||
auto initGlobal = llvm::cast<LLGlobalVariable>(initZ);
|
auto initGlobal = llvm::cast<LLGlobalVariable>(initZ);
|
||||||
initZ = irs->setGlobalVarInitializer(initGlobal, ir->getDefaultInit());
|
initZ = irs->setGlobalVarInitializer(initGlobal, ir->getDefaultInit());
|
||||||
setLinkage(decl, initGlobal);
|
setLinkageAndVisibility(decl, initGlobal);
|
||||||
|
|
||||||
llvm::GlobalVariable *vtbl = ir->getVtblSymbol();
|
llvm::GlobalVariable *vtbl = ir->getVtblSymbol();
|
||||||
defineGlobal(vtbl, ir->getVtblInit(), decl);
|
defineGlobal(vtbl, ir->getVtblInit(), decl);
|
||||||
|
|
|
@ -1790,12 +1790,12 @@ llvm::GlobalVariable *declareGlobal(const Loc &loc, llvm::Module &module,
|
||||||
}
|
}
|
||||||
|
|
||||||
void defineGlobal(llvm::GlobalVariable *global, llvm::Constant *init,
|
void defineGlobal(llvm::GlobalVariable *global, llvm::Constant *init,
|
||||||
Dsymbol *symbolForLinkage) {
|
Dsymbol *symbolForLinkageAndVisibility) {
|
||||||
assert(global->isDeclaration() && "Global variable already defined");
|
assert(global->isDeclaration() && "Global variable already defined");
|
||||||
assert(init);
|
assert(init);
|
||||||
global->setInitializer(init);
|
global->setInitializer(init);
|
||||||
if (symbolForLinkage)
|
if (symbolForLinkageAndVisibility)
|
||||||
setLinkage(symbolForLinkage, global);
|
setLinkageAndVisibility(symbolForLinkageAndVisibility, global);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::GlobalVariable *defineGlobal(const Loc &loc, llvm::Module &module,
|
llvm::GlobalVariable *defineGlobal(const Loc &loc, llvm::Module &module,
|
||||||
|
|
|
@ -254,10 +254,10 @@ llvm::GlobalVariable *declareGlobal(const Loc &loc, llvm::Module &module,
|
||||||
bool isThreadLocal = false);
|
bool isThreadLocal = false);
|
||||||
|
|
||||||
/// Defines an existing LLVM global, i.e., sets the initial value and finalizes
|
/// Defines an existing LLVM global, i.e., sets the initial value and finalizes
|
||||||
/// its linkage.
|
/// its linkage and visibility.
|
||||||
/// Asserts that a global isn't defined multiple times this way.
|
/// Asserts that a global isn't defined multiple times this way.
|
||||||
void defineGlobal(llvm::GlobalVariable *global, llvm::Constant *init,
|
void defineGlobal(llvm::GlobalVariable *global, llvm::Constant *init,
|
||||||
Dsymbol *symbolForLinkage);
|
Dsymbol *symbolForLinkageAndVisibility);
|
||||||
|
|
||||||
/// Declares (if not already declared) & defines an LLVM global.
|
/// Declares (if not already declared) & defines an LLVM global.
|
||||||
llvm::GlobalVariable *defineGlobal(const Loc &loc, llvm::Module &module,
|
llvm::GlobalVariable *defineGlobal(const Loc &loc, llvm::Module &module,
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "dmd/id.h"
|
#include "dmd/id.h"
|
||||||
#include "dmd/init.h"
|
#include "dmd/init.h"
|
||||||
#include "dmd/module.h"
|
#include "dmd/module.h"
|
||||||
|
#include "driver/cl_options.h"
|
||||||
#include "gen/abi.h"
|
#include "gen/abi.h"
|
||||||
#include "gen/arrays.h"
|
#include "gen/arrays.h"
|
||||||
#include "gen/classes.h"
|
#include "gen/classes.h"
|
||||||
|
@ -243,8 +244,14 @@ void setLinkage(LinkageWithCOMDAT lwc, llvm::GlobalObject *obj) {
|
||||||
obj->setComdat(gIR->module.getOrInsertComdat(obj->getName()));
|
obj->setComdat(gIR->module.getOrInsertComdat(obj->getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLinkage(Dsymbol *sym, llvm::GlobalObject *obj) {
|
void setLinkageAndVisibility(Dsymbol *sym, llvm::GlobalObject *obj) {
|
||||||
setLinkage(DtoLinkage(sym), obj);
|
setLinkage(DtoLinkage(sym), obj);
|
||||||
|
setVisibility(sym, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setVisibility(Dsymbol *sym, llvm::GlobalObject *obj) {
|
||||||
|
if (opts::defaultToHiddenVisibility && !sym->isExport())
|
||||||
|
obj->setVisibility(LLGlobalValue::HiddenVisibility);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -71,7 +71,12 @@ LinkageWithCOMDAT DtoLinkage(Dsymbol *sym);
|
||||||
|
|
||||||
bool supportsCOMDAT();
|
bool supportsCOMDAT();
|
||||||
void setLinkage(LinkageWithCOMDAT lwc, llvm::GlobalObject *obj);
|
void setLinkage(LinkageWithCOMDAT lwc, llvm::GlobalObject *obj);
|
||||||
void setLinkage(Dsymbol *sym, llvm::GlobalObject *obj);
|
// Sets the linkage of the specified IR global and possibly hides it, both based
|
||||||
|
// on the specified D symbol.
|
||||||
|
void setLinkageAndVisibility(Dsymbol *sym, llvm::GlobalObject *obj);
|
||||||
|
// Hides the specified IR global if using `-fvisibility=hidden` and the
|
||||||
|
// specified D symbol is not exported.
|
||||||
|
void setVisibility(Dsymbol *sym, llvm::GlobalObject *obj);
|
||||||
|
|
||||||
// some types
|
// some types
|
||||||
LLIntegerType *DtoSize_t();
|
LLIntegerType *DtoSize_t();
|
||||||
|
|
|
@ -666,6 +666,8 @@ void TypeInfoDeclaration_codegen(TypeInfoDeclaration *decl, IRState *p) {
|
||||||
decl->accept(&v);
|
decl->accept(&v);
|
||||||
|
|
||||||
setLinkage({TYPEINFO_LINKAGE_TYPE, supportsCOMDAT()}, gvar);
|
setLinkage({TYPEINFO_LINKAGE_TYPE, supportsCOMDAT()}, gvar);
|
||||||
|
if (auto forStructType = forType->isTypeStruct())
|
||||||
|
setVisibility(forStructType->sym, gvar);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
55
tests/codegen/export_aggregate_symbols.d
Normal file
55
tests/codegen/export_aggregate_symbols.d
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
// Tests -fvisibility={default,hidden} for special symbols generated for
|
||||||
|
// aggregates on non-Windows targets.
|
||||||
|
|
||||||
|
// UNSUPPORTED: Windows
|
||||||
|
|
||||||
|
// RUN: %ldc %s -shared -fvisibility=default -of=lib%t_default%so
|
||||||
|
// RUN: nm -g lib%t_default%so | FileCheck -check-prefix=DEFAULT -check-prefix=BOTH %s
|
||||||
|
|
||||||
|
// RUN: %ldc %s -shared -fvisibility=hidden -of=lib%t_hidden%so
|
||||||
|
// RUN: nm -g lib%t_hidden%so | FileCheck -check-prefix=HIDDEN -check-prefix=BOTH %s
|
||||||
|
|
||||||
|
|
||||||
|
// DEFAULT: _D24export_aggregate_symbols8DefaultC11__interface24export_aggregate_symbols8DefaultI{{.*}}__vtblZ
|
||||||
|
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultC11__interface24export_aggregate_symbols8DefaultI{{.*}}__vtblZ
|
||||||
|
// DEFAULT: _D24export_aggregate_symbols8DefaultC16__interfaceInfosZ
|
||||||
|
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultC16__interfaceInfosZ
|
||||||
|
// DEFAULT: _D24export_aggregate_symbols8DefaultC6__initZ
|
||||||
|
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultC6__initZ
|
||||||
|
// DEFAULT: _D24export_aggregate_symbols8DefaultC6__vtblZ
|
||||||
|
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultC6__vtblZ
|
||||||
|
// DEFAULT: _D24export_aggregate_symbols8DefaultC7__ClassZ
|
||||||
|
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultC7__ClassZ
|
||||||
|
class DefaultC : DefaultI { void foo() {} }
|
||||||
|
|
||||||
|
// DEFAULT: _D24export_aggregate_symbols8DefaultI11__InterfaceZ
|
||||||
|
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultI11__InterfaceZ
|
||||||
|
interface DefaultI { void foo(); }
|
||||||
|
|
||||||
|
// DEFAULT: _D24export_aggregate_symbols8DefaultS6__initZ
|
||||||
|
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultS6__initZ
|
||||||
|
struct DefaultS {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// BOTH: _D24export_aggregate_symbols9ExportedC11__interface24export_aggregate_symbols9ExportedI{{.*}}__vtblZ
|
||||||
|
// BOTH: _D24export_aggregate_symbols9ExportedC16__interfaceInfosZ
|
||||||
|
// BOTH: _D24export_aggregate_symbols9ExportedC6__initZ
|
||||||
|
// BOTH: _D24export_aggregate_symbols9ExportedC6__vtblZ
|
||||||
|
// BOTH: _D24export_aggregate_symbols9ExportedC7__ClassZ
|
||||||
|
export class ExportedC : ExportedI { void foo() {} }
|
||||||
|
|
||||||
|
// BOTH: _D24export_aggregate_symbols9ExportedI11__InterfaceZ
|
||||||
|
export interface ExportedI { void foo(); }
|
||||||
|
|
||||||
|
// BOTH: _D24export_aggregate_symbols9ExportedS6__initZ
|
||||||
|
export struct ExportedS {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// struct TypeInfos:
|
||||||
|
|
||||||
|
// DEFAULT: _D45TypeInfo_S24export_aggregate_symbols8DefaultS6__initZ
|
||||||
|
// HIDDEN-NOT: _D45TypeInfo_S24export_aggregate_symbols8DefaultS6__initZ
|
||||||
|
|
||||||
|
// BOTH: _D46TypeInfo_S24export_aggregate_symbols9ExportedS6__initZ
|
|
@ -3,10 +3,10 @@
|
||||||
|
|
||||||
// UNSUPPORTED: Windows
|
// UNSUPPORTED: Windows
|
||||||
|
|
||||||
// RUN: ldc2 %s -betterC -shared -fvisibility=default -of=lib%t_default%so
|
// RUN: %ldc %s -betterC -shared -fvisibility=default -of=lib%t_default%so
|
||||||
// RUN: nm -g lib%t_default%so | FileCheck -check-prefix=DEFAULT %s
|
// RUN: nm -g lib%t_default%so | FileCheck -check-prefix=DEFAULT %s
|
||||||
|
|
||||||
// RUN: ldc2 %s -betterC -shared -fvisibility=hidden -of=lib%t_hidden%so
|
// RUN: %ldc %s -betterC -shared -fvisibility=hidden -of=lib%t_hidden%so
|
||||||
// RUN: nm -g lib%t_hidden%so | FileCheck -check-prefix=HIDDEN %s
|
// RUN: nm -g lib%t_hidden%so | FileCheck -check-prefix=HIDDEN %s
|
||||||
|
|
||||||
extern(C) export int test__exportedFun() { return 42; }
|
extern(C) export int test__exportedFun() { return 42; }
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
|
|
||||||
// UNSUPPORTED: Windows
|
// UNSUPPORTED: Windows
|
||||||
|
|
||||||
// RUN: ldc2 %S/inputs/export_marked_symbols_lib.d -shared -of=%t_lib%so
|
// RUN: %ldc %S/inputs/export_marked_symbols_lib.d -shared -of=%t_lib%so
|
||||||
// RUN: ldc2 %s -I%S/inputs -fvisibility=hidden -of=%t%exe %t_lib%so
|
// RUN: %ldc %s -I%S/inputs -fvisibility=hidden -of=%t%exe %t_lib%so
|
||||||
// RUN: ldc2 %s -I%S/inputs -fvisibility=hidden -of=%t%exe %t_lib%so -d-version=DECLARE_MANUALLY
|
// RUN: %ldc %s -I%S/inputs -fvisibility=hidden -of=%t%exe %t_lib%so -d-version=DECLARE_MANUALLY
|
||||||
|
|
||||||
version (DECLARE_MANUALLY)
|
version (DECLARE_MANUALLY)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
// REQUIRES: LTO
|
// REQUIRES: LTO
|
||||||
|
|
||||||
// RUN: ldc2 %S/inputs/export_marked_symbols_lib.d -c -fvisibility=hidden -flto=thin -of=%t_lib%obj
|
// RUN: %ldc %S/inputs/export_marked_symbols_lib.d -c -fvisibility=hidden -flto=thin -of=%t_lib%obj
|
||||||
// RUN: ldc2 %s -I%S/inputs -flto=thin -of=%t%exe %t_lib%obj
|
// RUN: %ldc %s -I%S/inputs -flto=thin -of=%t%exe %t_lib%obj
|
||||||
|
|
||||||
import export_marked_symbols_lib;
|
import export_marked_symbols_lib;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue