r210368 - MS ABI: Update the thunk linkage computation
Hans Wennborg
hans at hanshq.net
Fri Jun 6 13:04:01 PDT 2014
Author: hans
Date: Fri Jun 6 15:04:01 2014
New Revision: 210368
URL: http://llvm.org/viewvc/llvm-project?rev=210368&view=rev
Log:
MS ABI: Update the thunk linkage computation
As suggested by Reid:
- class has GVA_Internal linkage -> internal
- thunk has return adjustment -> weak_odr, to handle evil corner case [1]
- all other normal methods -> linkonce_odr
1. Evil corner case:
struct Incomplete;
struct A { int a; virtual A *bar(); };
struct B { int b; virtual B *foo(Incomplete); };
struct C : A, B { int c; virtual C *foo(Incomplete); };
C c;
Here, the thunk for C::foo() will be emitted when C::foo() is defined, which
might be in a different translation unit, so it needs to be weak_odr.
Differential Revision: http://reviews.llvm.org/D3992
Modified:
cfe/trunk/lib/CodeGen/CGCXXABI.h
cfe/trunk/lib/CodeGen/CGVTables.cpp
cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
cfe/trunk/test/CodeGenCXX/dllimport.cpp
cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp
cfe/trunk/test/CodeGenCXX/microsoft-abi-thunks.cpp
cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=210368&r1=210367&r2=210368&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXABI.h (original)
+++ cfe/trunk/lib/CodeGen/CGCXXABI.h Fri Jun 6 15:04:01 2014
@@ -359,7 +359,8 @@ public:
/// base tables.
virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD) = 0;
- virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable) = 0;
+ virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable,
+ GlobalDecl GD, bool ReturnAdjustment) = 0;
virtual llvm::Value *performThisAdjustment(CodeGenFunction &CGF,
llvm::Value *This,
Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=210368&r1=210367&r2=210368&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Fri Jun 6 15:04:01 2014
@@ -382,12 +382,14 @@ void CodeGenVTables::emitThunk(GlobalDec
// FIXME: Do something better here; GenerateVarArgsThunk is extremely ugly.
if (!UseAvailableExternallyLinkage) {
CodeGenFunction(CGM).GenerateVarArgsThunk(ThunkFn, FnInfo, GD, Thunk);
- CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable);
+ CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD,
+ !Thunk.Return.isEmpty());
}
} else {
// Normal thunk body generation.
CodeGenFunction(CGM).GenerateThunk(ThunkFn, FnInfo, GD, Thunk);
- CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable);
+ CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD,
+ !Thunk.Return.isEmpty());
}
}
Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=210368&r1=210367&r2=210368&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Fri Jun 6 15:04:01 2014
@@ -174,7 +174,8 @@ public:
void emitVirtualInheritanceTables(const CXXRecordDecl *RD) override;
- void setThunkLinkage(llvm::Function *Thunk, bool ForVTable) override {
+ void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD,
+ bool ReturnAdjustment) override {
// Allow inlining of thunks by emitting them with available_externally
// linkage together with vtables when needed.
if (ForVTable)
Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=210368&r1=210367&r2=210368&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Fri Jun 6 15:04:01 2014
@@ -201,11 +201,20 @@ public:
void emitVBTableDefinition(const VPtrInfo &VBT, const CXXRecordDecl *RD,
llvm::GlobalVariable *GV) const;
- void setThunkLinkage(llvm::Function *Thunk, bool ForVTable) override {
- Thunk->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
-
+ void setThunkLinkage(llvm::Function *Thunk, bool ForVTable,
+ GlobalDecl GD, bool ReturnAdjustment) override {
// Never dllimport/dllexport thunks.
Thunk->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
+
+ GVALinkage Linkage =
+ getContext().GetGVALinkageForFunction(cast<FunctionDecl>(GD.getDecl()));
+
+ if (Linkage == GVA_Internal)
+ Thunk->setLinkage(llvm::GlobalValue::InternalLinkage);
+ else if (ReturnAdjustment)
+ Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
+ else
+ Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
}
llvm::Value *performThisAdjustment(CodeGenFunction &CGF, llvm::Value *This,
Modified: cfe/trunk/test/CodeGenCXX/dllimport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllimport.cpp?rev=210368&r1=210367&r2=210368&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/dllimport.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/dllimport.cpp Fri Jun 6 15:04:01 2014
@@ -566,7 +566,7 @@ namespace DontUseDtorAlias {
namespace Vtordisp {
// Don't dllimport the vtordisp.
- // MO1-DAG: define weak x86_thiscallcc void @"\01?f@?$C at D@Vtordisp@@$4PPPPPPPM at A@AEXXZ"
+ // MO1-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$C at D@Vtordisp@@$4PPPPPPPM at A@AEXXZ"
class Base {
virtual void f() {}
Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp?rev=210368&r1=210367&r2=210368&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp Fri Jun 6 15:04:01 2014
@@ -153,7 +153,7 @@ C::~C() {
void foo() {
C c;
}
-// DTORS2-LABEL: define weak x86_thiscallcc void @"\01??_EC at dtor_in_second_nvbase@@W3AEPAXI at Z"
+// DTORS2-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_EC at dtor_in_second_nvbase@@W3AEPAXI at Z"
// DTORS2: (%"struct.dtor_in_second_nvbase::C"* %this, i32 %should_call_delete)
// Do an adjustment from B* to C*.
// DTORS2: getelementptr i8* %{{.*}}, i32 -4
Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-thunks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-thunks.cpp?rev=210368&r1=210367&r2=210368&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-thunks.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-thunks.cpp Fri Jun 6 15:04:01 2014
@@ -61,13 +61,13 @@ struct C : A, B {
C::C() {} // Emits vftable and forces thunk generation.
-// CODEGEN-LABEL: define weak x86_thiscallcc void @"\01??_EC@@W3AEPAXI at Z"(%struct.C* %this, i32 %should_call_delete)
+// CODEGEN-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_EC@@W3AEPAXI at Z"(%struct.C* %this, i32 %should_call_delete)
// CODEGEN: getelementptr i8* {{.*}}, i32 -4
// FIXME: should actually call _EC, not _GC.
// CODEGEN: call x86_thiscallcc void @"\01??_GC@@UAEPAXI at Z"
// CODEGEN: ret
-// CODEGEN-LABEL: define weak x86_thiscallcc void @"\01?public_f at C@@W3AEXXZ"(%struct.C*
+// CODEGEN-LABEL: define linkonce_odr x86_thiscallcc void @"\01?public_f at C@@W3AEXXZ"(%struct.C*
// CODEGEN: getelementptr i8* {{.*}}, i32 -4
// CODEGEN: call x86_thiscallcc void @"\01?public_f at C@@UAEXXZ"(%struct.C*
// CODEGEN: ret
@@ -91,7 +91,7 @@ struct E : D {
E::E() {} // Emits vftable and forces thunk generation.
-// CODEGEN-LABEL: define weak x86_thiscallcc %struct.C* @"\01?goo at E@@QAEPAUB@@XZ"
+// CODEGEN-LABEL: define weak_odr x86_thiscallcc %struct.C* @"\01?goo at E@@QAEPAUB@@XZ"
// CODEGEN: call x86_thiscallcc %struct.C* @"\01?goo at E@@UAEPAUC@@XZ"
// CODEGEN: getelementptr inbounds i8* {{.*}}, i32 4
// CODEGEN: ret
@@ -124,7 +124,7 @@ struct I : D {
I::I() {} // Emits vftable and forces thunk generation.
-// CODEGEN-LABEL: define weak x86_thiscallcc %struct.{{[BF]}}* @"\01?goo at I@@QAEPAUB@@XZ"
+// CODEGEN-LABEL: define weak_odr x86_thiscallcc %struct.{{[BF]}}* @"\01?goo at I@@QAEPAUB@@XZ"
// CODEGEN: %[[ORIG_RET:.*]] = call x86_thiscallcc %struct.F* @"\01?goo at I@@UAEPAUF@@XZ"
// CODEGEN: %[[ORIG_RET_i8:.*]] = bitcast %struct.F* %[[ORIG_RET]] to i8*
// CODEGEN: %[[VBPTR_i8:.*]] = getelementptr inbounds i8* %[[ORIG_RET_i8]], i32 4
@@ -152,3 +152,14 @@ struct C : A, B {
};
C c;
}
+
+namespace {
+struct E : D {
+ E();
+ virtual C* goo();
+};
+E::E() {}
+E e;
+// Class with internal linkage has internal linkage thunks.
+// CODEGEN: define internal x86_thiscallcc %struct.C* @"\01?goo at E@?A@@QAEPAUB@@XZ"
+}
Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp?rev=210368&r1=210367&r2=210368&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp Fri Jun 6 15:04:01 2014
@@ -23,7 +23,7 @@ struct D : virtual C {
D::D() {} // Forces vftable emission.
-// CHECK-LABEL: define weak x86_thiscallcc void @"\01?f at D@@$4PPPPPPPM at A@AEXXZ"
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f at D@@$4PPPPPPPM at A@AEXXZ"
// CHECK: %[[ECX:.*]] = load %struct.D** %{{.*}}
// CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8*
// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 -4
@@ -34,7 +34,7 @@ D::D() {} // Forces vftable emission.
// CHECK: call x86_thiscallcc void @"\01?f at D@@UAEXXZ"(i8* %[[ADJUSTED_i8]])
// CHECK: ret void
-// CHECK-LABEL: define weak x86_thiscallcc void @"\01?f at D@@$4PPPPPPPI at 3AEXXZ"
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f at D@@$4PPPPPPPI at 3AEXXZ"
// CHECK: %[[ECX:.*]] = load %struct.D** %{{.*}}
// CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8*
// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 -8
@@ -63,7 +63,7 @@ struct G : virtual F, virtual E {
G::G() {} // Forces vftable emission.
-// CHECK-LABEL: define weak x86_thiscallcc void @"\01?f at E@@$R4BA at M@PPPPPPPM at 7AEXXZ"(i8*)
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f at E@@$R4BA at M@PPPPPPPM at 7AEXXZ"(i8*)
// CHECK: %[[ECX:.*]] = load %struct.E** %{{.*}}
// CHECK: %[[ECX_i8:.*]] = bitcast %struct.E* %[[ECX]] to i8*
// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 -4
Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp?rev=210368&r1=210367&r2=210368&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp Fri Jun 6 15:04:01 2014
@@ -145,7 +145,7 @@ struct X: virtual C {
// MANGLING-DAG: @"\01??_7X at Test4@@6B@"
// Also check the mangling of the thunk.
- // MANGLING-DAG: define weak x86_thiscallcc void @"\01?f at C@@WPPPPPPPI at AEXXZ"
+ // MANGLING-DAG: define linkonce_odr x86_thiscallcc void @"\01?f at C@@WPPPPPPPI at AEXXZ"
};
X::X() {}
More information about the cfe-commits
mailing list