diff --git a/gen/functions.cpp b/gen/functions.cpp index 1034d016ea..00d0a01abe 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -574,13 +574,6 @@ void DtoDeclareFunction(FuncDeclaration *fdecl) { : 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; // 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) { return; } @@ -1002,6 +989,16 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) { 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 { if (irFunc->isDynamicCompiled()) { defineDynamicCompiledFunction(gIR, irFunc); diff --git a/tests/codegen/export_marked_symbols1.d b/tests/codegen/export_marked_symbols1.d index 3b205386ea..8a3f7f1f9d 100644 --- a/tests/codegen/export_marked_symbols1.d +++ b/tests/codegen/export_marked_symbols1.d @@ -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 -// RUN: ldc2 %s -betterC -shared -fvisibility=hidden -of=lib%t.so -// RUN: nm -g lib%t.so | FileCheck %s +// RUN: ldc2 %s -betterC -shared -fvisibility=default -of=lib%t_default%so +// RUN: nm -g lib%t_default%so | FileCheck -check-prefix=DEFAULT %s -// CHECK: test__exportedFunDef -// CHECK: test__exportedVarDef -// CHECK-NOT: test__nonExportedFunDecl -// CHECK-NOT: test__nonExportedFunDef -// CHECK-NOT: test__nonExportedVarDecl -// CHECK-NOT: test__nonExportedVarDef +// RUN: ldc2 %s -betterC -shared -fvisibility=hidden -of=lib%t_hidden%so +// RUN: nm -g lib%t_hidden%so | FileCheck -check-prefix=HIDDEN %s +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__nonExportedFunDef() { return 101; } - -extern(C) export int test__exportedFunDecl(); -extern(C) int test__nonExportedFunDecl(); - -extern(C) export int test__exportedVarDef; -extern(C) int test__nonExportedVarDef; - -extern(C) extern export int test__exportedVarDecl; -extern(C) extern int test__nonExportedVarDecl; +extern(C) int test__nonExportedFun() { return 101; } +// DEFAULT: test__nonExportedFun +// HIDDEN-NOT: test__nonExportedFun +extern(C) int test__nonExportedVar; +// DEFAULT: test__nonExportedVar +// HIDDEN-NOT: test__nonExportedVar diff --git a/tests/codegen/export_marked_symbols2.d b/tests/codegen/export_marked_symbols2.d index e487fef630..8df3b6ec68 100644 --- a/tests/codegen/export_marked_symbols2.d +++ b/tests/codegen/export_marked_symbols2.d @@ -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 -// RUN: ldc2 %s -betterC -shared -fvisibility=default -of=lib%t.so -// RUN: nm -g lib%t.so | FileCheck %s +// RUN: ldc2 %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: ldc2 %s -I%S/inputs -fvisibility=hidden -of=%t%exe %t_lib%so -d-version=DECLARE_MANUALLY -// CHECK: test__exportedFunDef -// CHECK: test__exportedVarDef -// CHECK-NOT: test__nonExportedFunDecl -// CHECK: test__nonExportedFunDef -// CHECK-NOT: test__nonExportedVarDecl -// CHECK: test__nonExportedVarDef +version (DECLARE_MANUALLY) +{ + extern(C++): + export extern __gshared int exportedGlobal; + extern __gshared int normalGlobal; -extern(C) export int test__exportedFunDef() { return 42; } -extern(C) int test__nonExportedFunDef() { return 101; } + export void exportedFoo(); + void normalFoo(); +} +else +{ + import export_marked_symbols_lib; +} -extern(C) export int test__exportedFunDecl(); -extern(C) int test__nonExportedFunDecl(); +void main() +{ + exportedGlobal = 1; + normalGlobal = 2; -extern(C) export int test__exportedVarDef; -extern(C) int test__nonExportedVarDef; - -extern(C) extern export int test__exportedVarDecl; -extern(C) extern int test__nonExportedVarDecl; + exportedFoo(); + normalFoo(); +} diff --git a/tests/codegen/export_marked_symbols_thin_lto.d b/tests/codegen/export_marked_symbols_thin_lto.d index 7d67c66c72..96d9152cce 100644 --- a/tests/codegen/export_marked_symbols_thin_lto.d +++ b/tests/codegen/export_marked_symbols_thin_lto.d @@ -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 -// RUN: ldc2 %S/inputs/export_marked_symbols_thin_lto_lib.d -c -fvisibility=hidden -flto=thin -of=%t1%obj -// RUN: ldc2 %s -I%S/inputs -c -flto=thin -of=%t2%obj -// RUN: ldc2 %t1%obj %t2%obj -flto=thin +// RUN: ldc2 %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 -import export_marked_symbols_thin_lto_lib; +import export_marked_symbols_lib; void main() { + exportedGlobal = 1; + normalGlobal = 2; // declared in this module with default visibility, defined as hidden + exportedFoo(); - normalFoo(); + normalFoo(); // ditto } diff --git a/tests/codegen/inputs/export_marked_symbols_lib.d b/tests/codegen/inputs/export_marked_symbols_lib.d new file mode 100644 index 0000000000..5a042ecc85 --- /dev/null +++ b/tests/codegen/inputs/export_marked_symbols_lib.d @@ -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() {} diff --git a/tests/codegen/inputs/export_marked_symbols_thin_lto_lib.d b/tests/codegen/inputs/export_marked_symbols_thin_lto_lib.d deleted file mode 100644 index 5ff77784c8..0000000000 --- a/tests/codegen/inputs/export_marked_symbols_thin_lto_lib.d +++ /dev/null @@ -1,2 +0,0 @@ -export void exportedFoo() {} -void normalFoo() {} // hidden visibility diff --git a/tests/lit.site.cfg.in b/tests/lit.site.cfg.in index 4897ae705d..f6e0a4bd72 100644 --- a/tests/lit.site.cfg.in +++ b/tests/lit.site.cfg.in @@ -156,11 +156,16 @@ if (platform.system() == 'Windows'): config.substitutions.append( ('%obj', '.obj') ) config.substitutions.append( ('%exe', '.exe') ) config.substitutions.append( ('%lib', '.lib') ) + config.substitutions.append( ('%so', '.dll') ) config.substitutions.append( ('%diff_binary ', 'fc /b ') ) else: config.substitutions.append( ('%obj', '.o') ) config.substitutions.append( ('%exe', '') ) 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 ') ) # Add cdb substitution