From 279b5eb6910d64a293e9c0e2887a05c65d8737d7 Mon Sep 17 00:00:00 2001 From: John McCall Date: Thu, 12 Aug 2010 23:36:15 +0000 Subject: [PATCH] Just disable the hidden-visibility optimization for now by hiding it behind a -cc1 option. The Darwin linker complains about mixed visibility when linking gcc-built objects with clang-built objects, and the optimization isn't really that valuable. Platforms with less ornery linkers can feel free to enable this. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110979 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Driver/CC1Options.td | 2 ++ include/clang/Frontend/CodeGenOptions.h | 7 +++++-- lib/CodeGen/CGRTTI.cpp | 11 ++++++++--- lib/CodeGen/CGVTables.cpp | 5 ++++- lib/CodeGen/CodeGenModule.cpp | 5 ++++- lib/Frontend/CompilerInvocation.cpp | 1 + test/CodeGenCXX/exceptions-no-rtti.cpp | 10 +++++----- test/CodeGenCXX/key-function-vtable.cpp | 4 ++-- test/CodeGenCXX/rtti-linkage.cpp | 2 +- test/CodeGenCXX/thunks.cpp | 7 ++++--- test/CodeGenCXX/virt-template-vtable.cpp | 2 +- test/CodeGenCXX/vtable-key-function.cpp | 2 +- test/CodeGenCXX/vtable-linkage.cpp | 17 +++++++++++++++-- test/CodeGenObjCXX/rtti.mm | 14 +++++++------- test/SemaCXX/typeid-ref.cpp | 2 +- 15 files changed, 61 insertions(+), 30 deletions(-) diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index c83818a4b7..13d7e64be6 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -400,6 +400,8 @@ def ffreestanding : Flag<"-ffreestanding">, HelpText<"Assert that the compilation takes place in a freestanding environment">; def fgnu_runtime : Flag<"-fgnu-runtime">, HelpText<"Generate output compatible with the standard GNU Objective-C runtime">; +def fhidden_weak_vtables : Flag<"-fhidden-weak-vtables">, + HelpText<"Generate weak vtables and RTTI with hidden visibility">; def std_EQ : Joined<"-std=">, HelpText<"Language standard to compile for">; def fmath_errno : Flag<"-fmath-errno">, diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h index 63f247b5a9..0df8444cb1 100644 --- a/include/clang/Frontend/CodeGenOptions.h +++ b/include/clang/Frontend/CodeGenOptions.h @@ -50,8 +50,10 @@ public: /// various IR entities came from. Only useful /// when running CodeGen as a subroutine. unsigned FunctionSections : 1; /// Set when -ffunction-sections is enabled - unsigned EmitWeakTemplatesHidden : 1; /// Emit weak vtables and typeinfo for + unsigned HiddenWeakTemplateVTables : 1; /// Emit weak vtables and RTTI for /// template classes with hidden visibility + unsigned HiddenWeakVTables : 1; /// Emit weak vtables, RTTI, and thunks with + /// hidden visibility unsigned InstrumentFunctions : 1; /// Set when -finstrument-functions is enabled unsigned MergeAllConstants : 1; /// Merge identical constants. unsigned NoCommon : 1; /// Set when -fno-common or C++ is enabled. @@ -112,7 +114,8 @@ public: DisableRedZone = 0; EmitDeclMetadata = 0; FunctionSections = 0; - EmitWeakTemplatesHidden = 0; + HiddenWeakTemplateVTables = 0; + HiddenWeakVTables = 0; MergeAllConstants = 1; NoCommon = 0; NoImplicitFloat = 0; diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp index 69171419b6..a3ab6bad8f 100644 --- a/lib/CodeGen/CGRTTI.cpp +++ b/lib/CodeGen/CGRTTI.cpp @@ -11,9 +11,11 @@ // //===----------------------------------------------------------------------===// -#include "clang/AST/Type.h" -#include "clang/AST/RecordLayout.h" #include "CodeGenModule.h" +#include "clang/AST/RecordLayout.h" +#include "clang/AST/Type.h" +#include "clang/Frontend/CodeGenOptions.h" + using namespace clang; using namespace CodeGen; @@ -623,10 +625,13 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) { // GCC only relies on the uniqueness of the type names, not the // type_infos themselves, so we can emit these as hidden symbols. + // But don't do this if we're worried about strict visibility + // compatibility. if (const RecordType *RT = dyn_cast(Ty)) CGM.setTypeVisibility(GV, cast(RT->getDecl()), /*ForRTTI*/ true); - else if (Linkage == llvm::GlobalValue::WeakODRLinkage) + else if (CGM.getCodeGenOpts().HiddenWeakVTables && + Linkage == llvm::GlobalValue::WeakODRLinkage) GV->setVisibility(llvm::GlobalValue::HiddenVisibility); return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy); diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp index 494176a906..22701c2f69 100644 --- a/lib/CodeGen/CGVTables.cpp +++ b/lib/CodeGen/CGVTables.cpp @@ -2465,6 +2465,9 @@ static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD, const ThunkInfo &Thunk, llvm::Function *Fn) { CGM.setGlobalVisibility(Fn, MD); + if (!CGM.getCodeGenOpts().HiddenWeakVTables) + return; + // If the thunk has weak/linkonce linkage, but the function must be // emitted in every translation unit that references it, then we can // emit its thunks with hidden visibility, since its thunks must be @@ -2491,7 +2494,7 @@ static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD, case TSK_ExplicitSpecialization: case TSK_ImplicitInstantiation: - if (!CGM.getCodeGenOpts().EmitWeakTemplatesHidden) + if (!CGM.getCodeGenOpts().HiddenWeakTemplateVTables) return; break; } diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 6283b744c3..1715042691 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -225,6 +225,9 @@ void CodeGenModule::setTypeVisibility(llvm::GlobalValue *GV, bool IsForRTTI) const { setGlobalVisibility(GV, RD); + if (!CodeGenOpts.HiddenWeakVTables) + return; + // We want to drop the visibility to hidden for weak type symbols. // This isn't possible if there might be unresolved references // elsewhere that rely on this symbol being visible. @@ -260,7 +263,7 @@ void CodeGenModule::setTypeVisibility(llvm::GlobalValue *GV, // to deal with mixed-visibility symbols. case TSK_ExplicitSpecialization: case TSK_ImplicitInstantiation: - if (!CodeGenOpts.EmitWeakTemplatesHidden) + if (!CodeGenOpts.HiddenWeakTemplateVTables) return; break; } diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 2756c0784a..4ed4b07565 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -845,6 +845,7 @@ static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass); Opts.DisableFPElim = Args.hasArg(OPT_mdisable_fp_elim); Opts.FloatABI = Args.getLastArgValue(OPT_mfloat_abi); + Opts.HiddenWeakVTables = Args.hasArg(OPT_fhidden_weak_vtables); Opts.LimitFloatPrecision = Args.getLastArgValue(OPT_mlimit_float_precision); Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_mno_zero_initialized_in_bss); Opts.RelaxAll = Args.hasArg(OPT_mrelax_all); diff --git a/test/CodeGenCXX/exceptions-no-rtti.cpp b/test/CodeGenCXX/exceptions-no-rtti.cpp index 01be1cc4b0..66b4c4ac33 100644 --- a/test/CodeGenCXX/exceptions-no-rtti.cpp +++ b/test/CodeGenCXX/exceptions-no-rtti.cpp @@ -1,10 +1,10 @@ // RUN: %clang_cc1 -fno-rtti -fexceptions %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s -// CHECK: @_ZTIN5test11AE = weak_odr hidden constant -// CHECK: @_ZTIN5test11BE = weak_odr hidden constant -// CHECK: @_ZTIN5test11CE = weak_odr hidden constant -// CHECK: @_ZTIN5test11DE = weak_odr hidden constant -// CHECK: @_ZTIPN5test11DE = weak_odr hidden constant {{.*}} @_ZTIN5test11DE +// CHECK: @_ZTIN5test11AE = weak_odr constant +// CHECK: @_ZTIN5test11BE = weak_odr constant +// CHECK: @_ZTIN5test11CE = weak_odr constant +// CHECK: @_ZTIN5test11DE = weak_odr constant +// CHECK: @_ZTIPN5test11DE = weak_odr constant {{.*}} @_ZTIN5test11DE // PR6974: this shouldn't crash namespace test0 { diff --git a/test/CodeGenCXX/key-function-vtable.cpp b/test/CodeGenCXX/key-function-vtable.cpp index e71fba692f..15c058da94 100644 --- a/test/CodeGenCXX/key-function-vtable.cpp +++ b/test/CodeGenCXX/key-function-vtable.cpp @@ -47,5 +47,5 @@ void use_X1(X1 *x1) { x1->f(); } // CHECK: @_ZTV5testa = constant [3 x i8*] [i8* null // CHECK: @_ZTV5testc = weak_odr constant [3 x i8*] [i8* null // CHECK: @_ZTVN12_GLOBAL__N_15testgE = internal constant [3 x i8*] [i8* null -// CHECK: @_ZTV5teste = weak_odr hidden constant [3 x i8*] [i8* null -// CHECK: @_ZTV5testb = weak_odr hidden constant [3 x i8*] [i8* null +// CHECK: @_ZTV5teste = weak_odr constant [3 x i8*] [i8* null +// CHECK: @_ZTV5testb = weak_odr constant [3 x i8*] [i8* null diff --git a/test/CodeGenCXX/rtti-linkage.cpp b/test/CodeGenCXX/rtti-linkage.cpp index 49d1c1f5f3..efa336dda4 100644 --- a/test/CodeGenCXX/rtti-linkage.cpp +++ b/test/CodeGenCXX/rtti-linkage.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o - | sort | FileCheck %s +// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -fhidden-weak-vtables -emit-llvm -o - | sort | FileCheck %s // FIXME: Fails on Win32, dunno why. // XFAIL: win32 diff --git a/test/CodeGenCXX/thunks.cpp b/test/CodeGenCXX/thunks.cpp index 5ecaacb16a..ba60385ab6 100644 --- a/test/CodeGenCXX/thunks.cpp +++ b/test/CodeGenCXX/thunks.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fhidden-weak-vtables -emit-llvm -o - | FileCheck -check-prefix=HIDDEN %s namespace Test1 { @@ -251,8 +252,8 @@ namespace Test10 { struct B { virtual void foo(); }; struct C : A, B { void foo() {} }; - // CHECK: define linkonce_odr void @_ZN6Test101C3fooEv - // CHECK: define linkonce_odr hidden void @_ZThn8_N6Test101C3fooEv + // CHECK-HIDDEN: define linkonce_odr void @_ZN6Test101C3fooEv + // CHECK-HIDDEN: define linkonce_odr hidden void @_ZThn8_N6Test101C3fooEv void test() { C c; @@ -262,5 +263,5 @@ namespace Test10 { /**** The following has to go at the end of the file ****/ // This is from Test5: -// CHECK: define linkonce_odr hidden void @_ZTv0_n24_N5Test51B1fEv +// CHECK: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv // CHECK: define internal void @_ZThn8_N12_GLOBAL__N_11C1fEv( diff --git a/test/CodeGenCXX/virt-template-vtable.cpp b/test/CodeGenCXX/virt-template-vtable.cpp index b955828312..d60cfb9043 100644 --- a/test/CodeGenCXX/virt-template-vtable.cpp +++ b/test/CodeGenCXX/virt-template-vtable.cpp @@ -16,7 +16,7 @@ extern template class A; template class A; -// CHECK: @_ZTV1B = weak_odr hidden constant +// CHECK: @_ZTV1B = weak_odr constant // CHECK: @_ZTV1AIlE = weak_odr constant // CHECK: @_ZTV1AIsE = weak_odr constant // CHECK: @_ZTV1AIiE = weak_odr constant diff --git a/test/CodeGenCXX/vtable-key-function.cpp b/test/CodeGenCXX/vtable-key-function.cpp index bdcab230c6..97a546f8c9 100644 --- a/test/CodeGenCXX/vtable-key-function.cpp +++ b/test/CodeGenCXX/vtable-key-function.cpp @@ -9,7 +9,7 @@ struct A { // A does not have a key function, so the first constructor we emit should // cause the vtable to be defined (without assertions.) -// CHECK: @_ZTVN6PR56971AE = weak_odr hidden constant +// CHECK: @_ZTVN6PR56971AE = weak_odr constant A::A() { } A::A(int) { } } diff --git a/test/CodeGenCXX/vtable-linkage.cpp b/test/CodeGenCXX/vtable-linkage.cpp index 6c1301bee1..cf988d1312 100644 --- a/test/CodeGenCXX/vtable-linkage.cpp +++ b/test/CodeGenCXX/vtable-linkage.cpp @@ -1,10 +1,14 @@ // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o %t +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fhidden-weak-vtables -emit-llvm -o %t.hidden // RUN: FileCheck --check-prefix=CHECK-1 %s < %t // RUN: FileCheck --check-prefix=CHECK-2 %s < %t +// RUN: FileCheck --check-prefix=CHECK-2-HIDDEN %s < %t.hidden // RUN: FileCheck --check-prefix=CHECK-3 %s < %t // RUN: FileCheck --check-prefix=CHECK-4 %s < %t // RUN: FileCheck --check-prefix=CHECK-5 %s < %t +// RUN: FileCheck --check-prefix=CHECK-5-HIDDEN %s < %t.hidden // RUN: FileCheck --check-prefix=CHECK-6 %s < %t +// RUN: FileCheck --check-prefix=CHECK-6-HIDDEN %s < %t.hidden // RUN: FileCheck --check-prefix=CHECK-7 %s < %t // RUN: FileCheck --check-prefix=CHECK-8 %s < %t // RUN: FileCheck --check-prefix=CHECK-9 %s < %t @@ -99,9 +103,12 @@ void use_F() { // C has no key function, so its vtable should have weak_odr linkage // and hidden visibility (rdar://problem/7523229). -// CHECK-2: @_ZTV1C = weak_odr hidden constant +// CHECK-2: @_ZTV1C = weak_odr constant // CHECK-2: @_ZTS1C = weak_odr constant -// CHECK-2: @_ZTI1C = weak_odr hidden constant +// CHECK-2: @_ZTI1C = weak_odr constant +// CHECK-2-HIDDEN: @_ZTV1C = weak_odr hidden constant +// CHECK-2-HIDDEN: @_ZTS1C = weak_odr constant +// CHECK-2-HIDDEN: @_ZTI1C = weak_odr hidden constant // D has a key function that is defined in this translation unit so its vtable is // defined in the translation unit. @@ -122,12 +129,18 @@ void use_F() { // CHECK-5: @_ZTV1EIsE = weak_odr constant // CHECK-5: @_ZTS1EIsE = weak_odr constant // CHECK-5: @_ZTI1EIsE = weak_odr constant +// CHECK-5-HIDDEN: @_ZTV1EIsE = weak_odr constant +// CHECK-5-HIDDEN: @_ZTS1EIsE = weak_odr constant +// CHECK-5-HIDDEN: @_ZTI1EIsE = weak_odr constant // F is an explicit template instantiation without a key // function, so its vtable should have weak_odr linkage // CHECK-6: @_ZTV1FIsE = weak_odr constant // CHECK-6: @_ZTS1FIsE = weak_odr constant // CHECK-6: @_ZTI1FIsE = weak_odr constant +// CHECK-6-HIDDEN: @_ZTV1FIsE = weak_odr constant +// CHECK-6-HIDDEN: @_ZTS1FIsE = weak_odr constant +// CHECK-6-HIDDEN: @_ZTI1FIsE = weak_odr constant // E is an implicit template instantiation with a key function // defined in this translation unit, so its vtable should have diff --git a/test/CodeGenObjCXX/rtti.mm b/test/CodeGenObjCXX/rtti.mm index d24eaa62e2..27d24cb68e 100644 --- a/test/CodeGenObjCXX/rtti.mm +++ b/test/CodeGenObjCXX/rtti.mm @@ -4,19 +4,19 @@ namespace std { class type_info; } -// CHECK: @_ZTI1A = weak_odr hidden constant {{.*}}@_ZTVN10__cxxabiv117__class_type_infoE{{.*}}@_ZTS1A +// CHECK: @_ZTI1A = weak_odr constant {{.*}}@_ZTVN10__cxxabiv117__class_type_infoE{{.*}}@_ZTS1A @interface A @end -// CHECK: @_ZTI1B = weak_odr hidden constant {{.*}}@_ZTVN10__cxxabiv120__si_class_type_infoE{{.*}}@_ZTS1B{{.*}}@_ZTI1A +// CHECK: @_ZTI1B = weak_odr constant {{.*}}@_ZTVN10__cxxabiv120__si_class_type_infoE{{.*}}@_ZTS1B{{.*}}@_ZTI1A @interface B : A @end -// CHECK: @_ZTIP1B = weak_odr hidden constant {{.*}}@_ZTVN10__cxxabiv119__pointer_type_infoE{{.*}}@_ZTSP1B{{.*}}), i32 0, {{.*}}@_ZTI1B -// CHECK: @_ZTI11objc_object = weak_odr hidden constant {{.*}}@_ZTVN10__cxxabiv117__class_type_infoE{{.*}}@_ZTS11objc_object -// CHECK: @_ZTIP11objc_object = weak_odr hidden constant {{.*}}@_ZTVN10__cxxabiv119__pointer_type_infoE{{.*}}@_ZTSP11objc_object{{.*}}@_ZTI11objc_object -// CHECK: @_ZTI10objc_class = weak_odr hidden constant {{.*}}@_ZTVN10__cxxabiv117__class_type_infoE{{.*}}@_ZTS10objc_class -// CHECK: @_ZTIP10objc_class = weak_odr hidden constant {{.*}}@_ZTVN10__cxxabiv119__pointer_type_infoE{{.*}}@_ZTSP10objc_class{{.*}}@_ZTI10objc_class +// CHECK: @_ZTIP1B = weak_odr constant {{.*}}@_ZTVN10__cxxabiv119__pointer_type_infoE{{.*}}@_ZTSP1B{{.*}}), i32 0, {{.*}}@_ZTI1B +// CHECK: @_ZTI11objc_object = weak_odr constant {{.*}}@_ZTVN10__cxxabiv117__class_type_infoE{{.*}}@_ZTS11objc_object +// CHECK: @_ZTIP11objc_object = weak_odr constant {{.*}}@_ZTVN10__cxxabiv119__pointer_type_infoE{{.*}}@_ZTSP11objc_object{{.*}}@_ZTI11objc_object +// CHECK: @_ZTI10objc_class = weak_odr constant {{.*}}@_ZTVN10__cxxabiv117__class_type_infoE{{.*}}@_ZTS10objc_class +// CHECK: @_ZTIP10objc_class = weak_odr constant {{.*}}@_ZTVN10__cxxabiv119__pointer_type_infoE{{.*}}@_ZTSP10objc_class{{.*}}@_ZTI10objc_class @protocol P; diff --git a/test/SemaCXX/typeid-ref.cpp b/test/SemaCXX/typeid-ref.cpp index 362b919fa3..da0016970b 100644 --- a/test/SemaCXX/typeid-ref.cpp +++ b/test/SemaCXX/typeid-ref.cpp @@ -7,6 +7,6 @@ struct X { }; void f() { // CHECK: @_ZTS1X = weak_odr constant - // CHECK: @_ZTI1X = weak_odr hidden constant + // CHECK: @_ZTI1X = weak_odr constant (void)typeid(X&); } -- 2.40.0