From 065c61b64629d5ad969c0708b66294b05ccf1cbd Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sat, 7 Dec 2013 16:12:52 +0000 Subject: [PATCH] CodeGen: Don't emit linkage on thunks that aren't emitted because they're vararg. This can happen when we're trying to emit a thunk with available_externally linkage with optimization enabled but bail because it doesn't make sense for vararg functions. PR18098. llvm-svn: 196658 --- clang/lib/CodeGen/CGVTables.cpp | 7 ++++--- clang/test/CodeGenCXX/thunks.cpp | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 2fda9263f99a..81648cbef837 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -422,14 +422,15 @@ void CodeGenVTables::emitThunk(GlobalDecl GD, const ThunkInfo &Thunk, // expensive/sucky at the moment, so don't generate the thunk unless // we have to. // FIXME: Do something better here; GenerateVarArgsThunk is extremely ugly. - if (!UseAvailableExternallyLinkage) + if (!UseAvailableExternallyLinkage) { CodeGenFunction(CGM).GenerateVarArgsThunk(ThunkFn, FnInfo, GD, Thunk); + CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable); + } } else { // Normal thunk body generation. CodeGenFunction(CGM).GenerateThunk(ThunkFn, FnInfo, GD, Thunk); + CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable); } - - CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable); } void CodeGenVTables::maybeEmitThunkForVTable(GlobalDecl GD, diff --git a/clang/test/CodeGenCXX/thunks.cpp b/clang/test/CodeGenCXX/thunks.cpp index f5a85ef6b4d0..defb70681d93 100644 --- a/clang/test/CodeGenCXX/thunks.cpp +++ b/clang/test/CodeGenCXX/thunks.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o - -O1 -disable-llvm-optzns | FileCheck %s // RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -fhidden-weak-vtables -emit-llvm -o - | FileCheck -check-prefix=CHECK-HIDDEN %s namespace Test1 { @@ -342,6 +343,27 @@ namespace Test14 { // CHECK: define void @_ZThn8_N6Test141C1fEv({{.*}}) unnamed_addr [[NUW:#[0-9]+]] } +// Varargs non-covariant thunk test. +// PR18098 +namespace Test15 { + struct A { + virtual ~A(); + }; + struct B { + virtual void f(int x, ...); + }; + struct C : A, B { + virtual void c(); + virtual void f(int x, ...); + }; + void C::c() {} + + // C::c + // CHECK: declare void @_ZN6Test151C1fEiz + // non-virtual thunk to C::f + // CHECK: declare void @_ZThn8_N6Test151C1fEiz +} + /**** The following has to go at the end of the file ****/ // This is from Test5: