mirror of https://github.com/microsoft/clang.git
IRgen: Mark aliases of ctors and dtors as unnamed_addr.
This is not only semantically correct but ensures that they will not be marked as address-significant once D48155 lands. Differential Revision: https://reviews.llvm.org/D48206 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@334982 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ec4717bda8
commit
e614f166bb
|
@ -109,17 +109,8 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {
|
|||
D->getType()->getAs<FunctionType>()->getCallConv())
|
||||
return true;
|
||||
|
||||
return TryEmitDefinitionAsAlias(GlobalDecl(D, Dtor_Base),
|
||||
GlobalDecl(BaseD, Dtor_Base));
|
||||
}
|
||||
|
||||
/// Try to emit a definition as a global alias for another definition.
|
||||
/// If \p InEveryTU is true, we know that an equivalent alias can be produced
|
||||
/// in every translation unit.
|
||||
bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
|
||||
GlobalDecl TargetDecl) {
|
||||
if (!getCodeGenOpts().CXXCtorDtorAliases)
|
||||
return true;
|
||||
GlobalDecl AliasDecl(D, Dtor_Base);
|
||||
GlobalDecl TargetDecl(BaseD, Dtor_Base);
|
||||
|
||||
// The alias will use the linkage of the referent. If we can't
|
||||
// support aliases with that linkage, fail.
|
||||
|
@ -193,6 +184,9 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
|
|||
auto *Alias = llvm::GlobalAlias::create(AliasValueType, 0, Linkage, "",
|
||||
Aliasee, &getModule());
|
||||
|
||||
// Destructors are always unnamed_addr.
|
||||
Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
|
||||
|
||||
// Switch any previous uses to the alias.
|
||||
if (Entry) {
|
||||
assert(Entry->getType() == AliasType &&
|
||||
|
|
|
@ -1193,7 +1193,6 @@ public:
|
|||
/// are emitted lazily.
|
||||
void EmitGlobal(GlobalDecl D);
|
||||
|
||||
bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target);
|
||||
bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
|
||||
|
||||
llvm::GlobalValue *GetGlobalValue(StringRef Ref);
|
||||
|
|
|
@ -3693,6 +3693,9 @@ static void emitConstructorDestructorAlias(CodeGenModule &CGM,
|
|||
// Create the alias with no name.
|
||||
auto *Alias = llvm::GlobalAlias::create(Linkage, "", Aliasee);
|
||||
|
||||
// Constructors and destructors are always unnamed_addr.
|
||||
Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
|
||||
|
||||
// Switch any previous uses to the alias.
|
||||
if (Entry) {
|
||||
assert(Entry->getType() == Aliasee->getType() &&
|
||||
|
|
|
@ -9,4 +9,4 @@ struct B {
|
|||
B::B() {
|
||||
}
|
||||
|
||||
// CHECK: @_ZN1BC1Ev = alias void (%struct.B*), void (%struct.B*)* @_ZN1BC2Ev
|
||||
// CHECK: @_ZN1BC1Ev = unnamed_addr alias void (%struct.B*), void (%struct.B*)* @_ZN1BC2Ev
|
||||
|
|
|
@ -14,8 +14,8 @@ namespace test1 {
|
|||
// Test that we produce the appropriate comdats when creating aliases to
|
||||
// weak_odr constructors and destructors.
|
||||
|
||||
// CHECK1: @_ZN5test16foobarIvEC1Ev = weak_odr alias void {{.*}} @_ZN5test16foobarIvEC2Ev
|
||||
// CHECK1: @_ZN5test16foobarIvED1Ev = weak_odr alias void (%"struct.test1::foobar"*), void (%"struct.test1::foobar"*)* @_ZN5test16foobarIvED2Ev
|
||||
// CHECK1: @_ZN5test16foobarIvEC1Ev = weak_odr unnamed_addr alias void {{.*}} @_ZN5test16foobarIvEC2Ev
|
||||
// CHECK1: @_ZN5test16foobarIvED1Ev = weak_odr unnamed_addr alias void (%"struct.test1::foobar"*), void (%"struct.test1::foobar"*)* @_ZN5test16foobarIvED2Ev
|
||||
// CHECK1: define weak_odr void @_ZN5test16foobarIvEC2Ev({{.*}} comdat($_ZN5test16foobarIvEC5Ev)
|
||||
// CHECK1: define weak_odr void @_ZN5test16foobarIvED2Ev({{.*}} comdat($_ZN5test16foobarIvED5Ev)
|
||||
// CHECK1: define weak_odr void @_ZN5test16foobarIvED0Ev({{.*}} comdat($_ZN5test16foobarIvED5Ev)
|
||||
|
@ -141,7 +141,7 @@ namespace test7 {
|
|||
|
||||
namespace test8 {
|
||||
// Test that we replace ~zed with ~bar which is an alias to ~foo.
|
||||
// CHECK4: @_ZN5test83barD2Ev = alias {{.*}} @_ZN5test83fooD2Ev
|
||||
// CHECK4: @_ZN5test83barD2Ev = unnamed_addr alias {{.*}} @_ZN5test83fooD2Ev
|
||||
// CHECK4: define internal void @__cxx_global_var_init.5()
|
||||
// CHECK4: call i32 @__cxa_atexit({{.*}}@_ZN5test83barD2Ev
|
||||
struct foo {
|
||||
|
@ -232,8 +232,8 @@ struct foo : public bar {
|
|||
~foo();
|
||||
};
|
||||
foo::~foo() {}
|
||||
// CHECK6: @_ZN6test113fooD2Ev = alias {{.*}} @_ZN6test113barD2Ev
|
||||
// CHECK6: @_ZN6test113fooD1Ev = alias {{.*}} @_ZN6test113fooD2Ev
|
||||
// CHECK6: @_ZN6test113fooD2Ev = unnamed_addr alias {{.*}} @_ZN6test113barD2Ev
|
||||
// CHECK6: @_ZN6test113fooD1Ev = unnamed_addr alias {{.*}} @_ZN6test113fooD2Ev
|
||||
}
|
||||
|
||||
namespace test12 {
|
||||
|
@ -243,6 +243,6 @@ struct foo {
|
|||
};
|
||||
|
||||
template class foo<1>;
|
||||
// CHECK6: @_ZN6test123fooILi1EED1Ev = weak_odr alias {{.*}} @_ZN6test123fooILi1EED2Ev
|
||||
// CHECK6: @_ZN6test123fooILi1EED1Ev = weak_odr unnamed_addr alias {{.*}} @_ZN6test123fooILi1EED2Ev
|
||||
// CHECK6: define weak_odr void @_ZN6test123fooILi1EED2Ev({{.*}}) {{.*}} comdat($_ZN6test123fooILi1EED5Ev)
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ namespace test0 {
|
|||
|
||||
// complete destructor alias tested above
|
||||
|
||||
// CHECK2-LABEL: @_ZN5test01AD1Ev = alias {{.*}} @_ZN5test01AD2Ev
|
||||
// CHECK2-LABEL: @_ZN5test01AD1Ev = unnamed_addr alias {{.*}} @_ZN5test01AD2Ev
|
||||
// CHECK2-LABEL: define void @_ZN5test01AD2Ev(%"struct.test0::A"* %this) unnamed_addr
|
||||
// CHECK2: invoke void @_ZN5test06MemberD1Ev
|
||||
// CHECK2: unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
|
||||
|
@ -104,7 +104,7 @@ namespace test0 {
|
|||
// CHECK2: unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
|
||||
|
||||
// In C++11, the destructors are often known not to throw.
|
||||
// CHECK2v11-LABEL: @_ZN5test01AD1Ev = alias {{.*}} @_ZN5test01AD2Ev
|
||||
// CHECK2v11-LABEL: @_ZN5test01AD1Ev = unnamed_addr alias {{.*}} @_ZN5test01AD2Ev
|
||||
// CHECK2v11-LABEL: define void @_ZN5test01AD2Ev(%"struct.test0::A"* %this) unnamed_addr
|
||||
// CHECK2v11: call void @_ZN5test06MemberD1Ev
|
||||
// CHECK2v11: call void @_ZN5test04BaseD2Ev
|
||||
|
@ -153,15 +153,15 @@ namespace test1 {
|
|||
|
||||
struct M : A { ~M(); };
|
||||
M::~M() {}
|
||||
// CHECK3: @_ZN5test11MD2Ev = alias {{.*}} @_ZN5test11AD2Ev
|
||||
// CHECK3: @_ZN5test11MD2Ev = unnamed_addr alias {{.*}} @_ZN5test11AD2Ev
|
||||
|
||||
struct N : A, Empty { ~N(); };
|
||||
N::~N() {}
|
||||
// CHECK3: @_ZN5test11ND2Ev = alias {{.*}} @_ZN5test11AD2Ev
|
||||
// CHECK3: @_ZN5test11ND2Ev = unnamed_addr alias {{.*}} @_ZN5test11AD2Ev
|
||||
|
||||
struct O : Empty, A { ~O(); };
|
||||
O::~O() {}
|
||||
// CHECK3: @_ZN5test11OD2Ev = alias {{.*}} @_ZN5test11AD2Ev
|
||||
// CHECK3: @_ZN5test11OD2Ev = unnamed_addr alias {{.*}} @_ZN5test11AD2Ev
|
||||
|
||||
struct P : NonEmpty, A { ~P(); };
|
||||
P::~P() {} // CHECK3-LABEL: define void @_ZN5test11PD2Ev(%"struct.test1::P"* %this) unnamed_addr
|
||||
|
@ -174,7 +174,7 @@ namespace test1 {
|
|||
|
||||
struct S : A { ~S(); int x; };
|
||||
S::~S() {}
|
||||
// CHECK4: @_ZN5test11SD2Ev = alias {{.*}}, bitcast {{.*}} @_ZN5test11AD2Ev
|
||||
// CHECK4: @_ZN5test11SD2Ev = unnamed_addr alias {{.*}}, bitcast {{.*}} @_ZN5test11AD2Ev
|
||||
|
||||
struct T : A { ~T(); B x; };
|
||||
T::~T() {} // CHECK4-LABEL: define void @_ZN5test11TD2Ev(%"struct.test1::T"* %this) unnamed_addr
|
||||
|
|
|
@ -14,5 +14,5 @@ A::A() {}
|
|||
|
||||
A::~A() {}
|
||||
|
||||
// CHECK: @_ZN1AC1Ev = dso_local dllexport alias void (%class.A*), void (%class.A*)* @_ZN1AC2Ev
|
||||
// CHECK: @_ZN1AD1Ev = dso_local dllexport alias void (%class.A*), void (%class.A*)* @_ZN1AD2Ev
|
||||
// CHECK: @_ZN1AC1Ev = dso_local dllexport unnamed_addr alias void (%class.A*), void (%class.A*)* @_ZN1AC2Ev
|
||||
// CHECK: @_ZN1AD1Ev = dso_local dllexport unnamed_addr alias void (%class.A*), void (%class.A*)* @_ZN1AD2Ev
|
||||
|
|
|
@ -641,7 +641,7 @@ namespace UseDtorAlias {
|
|||
A::~A() { }
|
||||
B::~B() { }
|
||||
// Emit a alias definition of B's constructor.
|
||||
// M32-DAG: @"??1B@UseDtorAlias@@QAE@XZ" = dso_local dllexport alias {{.*}} @"??1A@UseDtorAlias@@QAE@XZ"
|
||||
// M32-DAG: @"??1B@UseDtorAlias@@QAE@XZ" = dso_local dllexport unnamed_addr alias {{.*}} @"??1A@UseDtorAlias@@QAE@XZ"
|
||||
}
|
||||
|
||||
struct __declspec(dllexport) DefaultedCtorsDtors {
|
||||
|
|
|
@ -22,7 +22,7 @@ B::~B() {}
|
|||
void foo() {
|
||||
B b;
|
||||
}
|
||||
// CHECK-DAG: @"??1B@test2@@UAE@XZ" = dso_local alias void (%"struct.test2::B"*), bitcast (void (%"struct.test2::A"*)* @"??1A@test2@@UAE@XZ" to void (%"struct.test2::B"*)*)
|
||||
// CHECK-DAG: @"??1B@test2@@UAE@XZ" = dso_local unnamed_addr alias void (%"struct.test2::B"*), bitcast (void (%"struct.test2::A"*)* @"??1A@test2@@UAE@XZ" to void (%"struct.test2::B"*)*)
|
||||
}
|
||||
|
||||
namespace test3 {
|
||||
|
|
|
@ -4,7 +4,7 @@ struct A {
|
|||
A();
|
||||
};
|
||||
|
||||
// CHECK: @_ZN1AC1Ev = alias {{.*}} @_ZN1AC2Ev
|
||||
// CHECK: @_ZN1AC1Ev = unnamed_addr alias {{.*}} @_ZN1AC2Ev
|
||||
// CHECK-LABEL: define void @_ZN1AC2Ev(%struct.A* %this) unnamed_addr
|
||||
A::A() { }
|
||||
|
||||
|
|
|
@ -14,11 +14,11 @@ struct B : A {
|
|||
};
|
||||
|
||||
// Complete dtor: just an alias because there are no virtual bases.
|
||||
// CHECK: @_ZN1BD1Ev = alias {{.*}} @_ZN1BD2Ev
|
||||
// CHECK: @_ZN1BD1Ev = unnamed_addr alias {{.*}} @_ZN1BD2Ev
|
||||
|
||||
// (aliases from C)
|
||||
// CHECK: @_ZN1CD2Ev = alias {{.*}}, bitcast {{.*}} @_ZN1BD2Ev
|
||||
// CHECK: @_ZN1CD1Ev = alias {{.*}} @_ZN1CD2Ev
|
||||
// CHECK: @_ZN1CD2Ev = unnamed_addr alias {{.*}}, bitcast {{.*}} @_ZN1BD2Ev
|
||||
// CHECK: @_ZN1CD1Ev = unnamed_addr alias {{.*}} @_ZN1CD2Ev
|
||||
|
||||
// Base dtor: actually calls A's base dtor.
|
||||
// CHECK-LABEL: define void @_ZN1BD2Ev(%struct.B* %this) unnamed_addr
|
||||
|
|
Loading…
Reference in New Issue