-fvisibility=hidden: Only hide function *definitions*, don't touch declarations (#2923)

This commit is contained in:
Martin Kinkelin 2018-12-03 20:59:59 +01:00 committed by GitHub
parent 7966987178
commit deaaab8cf3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 73 additions and 59 deletions

View file

@ -574,13 +574,6 @@ void DtoDeclareFunction(FuncDeclaration *fdecl) {
: LLGlobalValue::DLLExportStorageClass); : LLGlobalValue::DLLExportStorageClass);
} }
// Hide non-exported symbols
if (opts::defaultToHiddenVisibility &&
!fdecl->isImportedSymbol() &&
!fdecl->isExport()) {
func->setVisibility(LLGlobalValue::HiddenVisibility);
}
IF_LOG Logger::cout() << "func = " << *func << std::endl; IF_LOG Logger::cout() << "func = " << *func << std::endl;
// add func to IRFunc // add func to IRFunc
@ -981,12 +974,6 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
} }
} }
// if this function is naked, we take over right away! no standard processing!
if (fd->naked) {
DtoDefineNakedFunction(fd);
return;
}
if (!fd->fbody) { if (!fd->fbody) {
return; return;
} }
@ -1002,6 +989,16 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
return; return;
} }
if (opts::defaultToHiddenVisibility && !fd->isExport()) {
func->setVisibility(LLGlobalValue::HiddenVisibility);
}
// if this function is naked, we take over right away! no standard processing!
if (fd->naked) {
DtoDefineNakedFunction(fd);
return;
}
SCOPE_EXIT { SCOPE_EXIT {
if (irFunc->isDynamicCompiled()) { if (irFunc->isDynamicCompiled()) {
defineDynamicCompiledFunction(gIR, irFunc); defineDynamicCompiledFunction(gIR, irFunc);

View file

@ -1,26 +1,24 @@
// Test that passing -fvisibility=hidden hides all unexported symbols // Tests -fvisibility={default,hidden} for function definitions and
// (non-extern) globals on non-Windows targets.
// UNSUPPORTED: Windows // UNSUPPORTED: Windows
// RUN: ldc2 %s -betterC -shared -fvisibility=hidden -of=lib%t.so // RUN: ldc2 %s -betterC -shared -fvisibility=default -of=lib%t_default%so
// RUN: nm -g lib%t.so | FileCheck %s // RUN: nm -g lib%t_default%so | FileCheck -check-prefix=DEFAULT %s
// CHECK: test__exportedFunDef // RUN: ldc2 %s -betterC -shared -fvisibility=hidden -of=lib%t_hidden%so
// CHECK: test__exportedVarDef // RUN: nm -g lib%t_hidden%so | FileCheck -check-prefix=HIDDEN %s
// CHECK-NOT: test__nonExportedFunDecl
// CHECK-NOT: test__nonExportedFunDef
// CHECK-NOT: test__nonExportedVarDecl
// CHECK-NOT: test__nonExportedVarDef
extern(C) export int test__exportedFun() { return 42; }
// DEFAULT: test__exportedFun
// HIDDEN: test__exportedFun
extern(C) export int test__exportedVar;
// DEFAULT: test__exportedVar
// HIDDEN: test__exportedVar
extern(C) export int test__exportedFunDef() { return 42; } extern(C) int test__nonExportedFun() { return 101; }
extern(C) int test__nonExportedFunDef() { return 101; } // DEFAULT: test__nonExportedFun
// HIDDEN-NOT: test__nonExportedFun
extern(C) export int test__exportedFunDecl(); extern(C) int test__nonExportedVar;
extern(C) int test__nonExportedFunDecl(); // DEFAULT: test__nonExportedVar
// HIDDEN-NOT: test__nonExportedVar
extern(C) export int test__exportedVarDef;
extern(C) int test__nonExportedVarDef;
extern(C) extern export int test__exportedVarDecl;
extern(C) extern int test__nonExportedVarDecl;

View file

@ -1,26 +1,32 @@
// Test that compiling with -fvisibility=default exports all symbols on non-Windows targets // Tests that -fvisibility=hidden doesn't affect imported and fwd declared symbols,
// so that they can still be linked in from a shared library.
// UNSUPPORTED: Windows // UNSUPPORTED: Windows
// RUN: ldc2 %s -betterC -shared -fvisibility=default -of=lib%t.so // RUN: ldc2 %S/inputs/export_marked_symbols_lib.d -shared -of=%t_lib%so
// RUN: nm -g lib%t.so | FileCheck %s // RUN: ldc2 %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
// CHECK: test__exportedFunDef version (DECLARE_MANUALLY)
// CHECK: test__exportedVarDef {
// CHECK-NOT: test__nonExportedFunDecl extern(C++):
// CHECK: test__nonExportedFunDef
// CHECK-NOT: test__nonExportedVarDecl
// CHECK: test__nonExportedVarDef
export extern __gshared int exportedGlobal;
extern __gshared int normalGlobal;
extern(C) export int test__exportedFunDef() { return 42; } export void exportedFoo();
extern(C) int test__nonExportedFunDef() { return 101; } void normalFoo();
}
else
{
import export_marked_symbols_lib;
}
extern(C) export int test__exportedFunDecl(); void main()
extern(C) int test__nonExportedFunDecl(); {
exportedGlobal = 1;
normalGlobal = 2;
extern(C) export int test__exportedVarDef; exportedFoo();
extern(C) int test__nonExportedVarDef; normalFoo();
}
extern(C) extern export int test__exportedVarDecl;
extern(C) extern int test__nonExportedVarDecl;

View file

@ -1,15 +1,18 @@
// Test that -fvisibility=hidden works with thin LTO // Tests that mismatching symbol visibilities between declarations and definitions
// work with thin LTO.
// REQUIRES: LTO // REQUIRES: LTO
// RUN: ldc2 %S/inputs/export_marked_symbols_thin_lto_lib.d -c -fvisibility=hidden -flto=thin -of=%t1%obj // RUN: ldc2 %S/inputs/export_marked_symbols_lib.d -c -fvisibility=hidden -flto=thin -of=%t_lib%obj
// RUN: ldc2 %s -I%S/inputs -c -flto=thin -of=%t2%obj // RUN: ldc2 %s -I%S/inputs -flto=thin -of=%t%exe %t_lib%obj
// RUN: ldc2 %t1%obj %t2%obj -flto=thin
import export_marked_symbols_thin_lto_lib; import export_marked_symbols_lib;
void main() void main()
{ {
exportedGlobal = 1;
normalGlobal = 2; // declared in this module with default visibility, defined as hidden
exportedFoo(); exportedFoo();
normalFoo(); normalFoo(); // ditto
} }

View file

@ -0,0 +1,7 @@
extern(C++): // so that we can manually declare the symbols in another module too
export __gshared int exportedGlobal;
__gshared int normalGlobal;
export void exportedFoo() {}
void normalFoo() {}

View file

@ -1,2 +0,0 @@
export void exportedFoo() {}
void normalFoo() {} // hidden visibility

View file

@ -156,11 +156,16 @@ if (platform.system() == 'Windows'):
config.substitutions.append( ('%obj', '.obj') ) config.substitutions.append( ('%obj', '.obj') )
config.substitutions.append( ('%exe', '.exe') ) config.substitutions.append( ('%exe', '.exe') )
config.substitutions.append( ('%lib', '.lib') ) config.substitutions.append( ('%lib', '.lib') )
config.substitutions.append( ('%so', '.dll') )
config.substitutions.append( ('%diff_binary ', 'fc /b ') ) config.substitutions.append( ('%diff_binary ', 'fc /b ') )
else: else:
config.substitutions.append( ('%obj', '.o') ) config.substitutions.append( ('%obj', '.o') )
config.substitutions.append( ('%exe', '') ) config.substitutions.append( ('%exe', '') )
config.substitutions.append( ('%lib', '.a') ) config.substitutions.append( ('%lib', '.a') )
if (platform.system() == 'Darwin'):
config.substitutions.append( ('%so', '.dylib') )
else:
config.substitutions.append( ('%so', '.so') )
config.substitutions.append( ('%diff_binary ', 'cmp -s ') ) config.substitutions.append( ('%diff_binary ', 'cmp -s ') )
# Add cdb substitution # Add cdb substitution