]> granicus.if.org Git - clang/commitdiff
CodeGen: Don't emit linkage on thunks that aren't emitted because they're vararg.
authorBenjamin Kramer <benny.kra@googlemail.com>
Sat, 7 Dec 2013 16:12:52 +0000 (16:12 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Sat, 7 Dec 2013 16:12:52 +0000 (16:12 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196658 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGVTables.cpp
test/CodeGenCXX/thunks.cpp

index 2fda9263f99ad3ed838dae37356d5faf0aa656b6..81648cbef8374da5c59eb163e14dd4d397db827b 100644 (file)
@@ -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,
index f5a85ef6b4d03c80899ab164e7c34ea149ed1b04..defb70681d93d9c42047db7917d01abe41f6f14e 100644 (file)
@@ -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: