diff options
-rw-r--r-- | lib/CodeGen/CGVtable.cpp | 9 | ||||
-rw-r--r-- | test/CodeGenCXX/thunks.cpp | 29 |
2 files changed, 26 insertions, 12 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 65788259e6..4bdda985aa 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -3867,14 +3867,7 @@ void CodeGenFunction::GenerateThunk(llvm::Function *Fn, GlobalDecl GD, CXXThisDecl->Destroy(getContext()); // Set the right linkage. - llvm::GlobalValue::LinkageTypes ThunkLinkage; - - if (CGM.getFunctionLinkage(MD) == llvm::Function::InternalLinkage) - ThunkLinkage = llvm::Function::InternalLinkage; - else - ThunkLinkage = llvm::Function::WeakAnyLinkage; - - Fn->setLinkage(ThunkLinkage); + Fn->setLinkage(CGM.getFunctionLinkage(MD)); // Set the right visibility. CGM.setGlobalVisibility(Fn, MD); diff --git a/test/CodeGenCXX/thunks.cpp b/test/CodeGenCXX/thunks.cpp index 2389839921..b91ba3239b 100644 --- a/test/CodeGenCXX/thunks.cpp +++ b/test/CodeGenCXX/thunks.cpp @@ -18,7 +18,7 @@ struct C : A, B { virtual void f(); }; -// CHECK: define weak void @_ZThn8_N5Test11C1fEv( +// CHECK: define void @_ZThn8_N5Test11C1fEv( void C::f() { } } @@ -36,7 +36,7 @@ struct B : virtual A { virtual void f(); }; -// CHECK: define weak void @_ZTv0_n24_N5Test21B1fEv( +// CHECK: define void @_ZTv0_n24_N5Test21B1fEv( void B::f() { } } @@ -58,7 +58,7 @@ struct B : A { virtual V2 *f(); }; -// CHECK: define weak %{{.*}}* @_ZTch0_v0_n24_N5Test31B1fEv( +// CHECK: define %{{.*}}* @_ZTch0_v0_n24_N5Test31B1fEv( V2 *B::f() { return 0; } } @@ -81,11 +81,14 @@ struct __attribute__((visibility("protected"))) C : A, B { virtual void f(); }; -// CHECK: define weak protected void @_ZThn8_N5Test41C1fEv( +// CHECK: define protected void @_ZThn8_N5Test41C1fEv( void C::f() { } } +// This is from Test5: +// CHECK: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv + // Check that the thunk gets internal linkage. namespace { @@ -114,3 +117,21 @@ void f() { c.f(); } + +namespace Test5 { + +// Check that the thunk for 'B::f' gets the same linkage as the function itself. +struct A { + virtual void f(); +}; + +struct B : virtual A { + virtual void f() { } +}; + +void f(B b) { + b.f(); +} +} + + |