<div dir="ltr"><div>Emitting vtable thunks for vararg thunks make perfect sense.  LLVM just can't represent them yet.  ;)</div><div><br></div><div><div>In seriousness, we're going to need a way to thunks like these for the MSVC ABI.  Implementing general pointers to virtual member functions will require it, because the arguments cannot be copied and we may not have the body of the function to clone, like we do for vararg virtual methods in Itanium.</div>
</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sat, Dec 7, 2013 at 8:12 AM, Benjamin Kramer <span dir="ltr"><<a href="mailto:benny.kra@googlemail.com" target="_blank">benny.kra@googlemail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: d0k<br>
Date: Sat Dec  7 10:12:52 2013<br>
New Revision: 196658<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=196658&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=196658&view=rev</a><br>
Log:<br>
CodeGen: Don't emit linkage on thunks that aren't emitted because they're vararg.<br>
<br>
This can happen when we're trying to emit a thunk with available_externally<br>
linkage with optimization enabled but bail because it doesn't make sense<br>
for vararg functions.<br>
<br>
PR18098.<br>
<br>
Modified:<br>
    cfe/trunk/lib/CodeGen/CGVTables.cpp<br>
    cfe/trunk/test/CodeGenCXX/thunks.cpp<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=196658&r1=196657&r2=196658&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=196658&r1=196657&r2=196658&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Sat Dec  7 10:12:52 2013<br>
@@ -422,14 +422,15 @@ void CodeGenVTables::emitThunk(GlobalDec<br>
     // expensive/sucky at the moment, so don't generate the thunk unless<br>
     // we have to.<br>
     // FIXME: Do something better here; GenerateVarArgsThunk is extremely ugly.<br>
-    if (!UseAvailableExternallyLinkage)<br>
+    if (!UseAvailableExternallyLinkage) {<br>
       CodeGenFunction(CGM).GenerateVarArgsThunk(ThunkFn, FnInfo, GD, Thunk);<br>
+      CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable);<br>
+    }<br>
   } else {<br>
     // Normal thunk body generation.<br>
     CodeGenFunction(CGM).GenerateThunk(ThunkFn, FnInfo, GD, Thunk);<br>
+    CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable);<br>
   }<br>
-<br>
-  CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable);<br>
 }<br>
<br>
 void CodeGenVTables::maybeEmitThunkForVTable(GlobalDecl GD,<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/thunks.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/thunks.cpp?rev=196658&r1=196657&r2=196658&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/thunks.cpp?rev=196658&r1=196657&r2=196658&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/thunks.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/thunks.cpp Sat Dec  7 10:12:52 2013<br>
@@ -1,4 +1,5 @@<br>
 // RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o - | FileCheck %s<br>
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o - -O1 -disable-llvm-optzns | FileCheck %s<br>
 // RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -fhidden-weak-vtables -emit-llvm -o - | FileCheck -check-prefix=CHECK-HIDDEN %s<br>
<br>
 namespace Test1 {<br>
@@ -342,6 +343,27 @@ namespace Test14 {<br>
   // CHECK: define void @_ZThn8_N6Test141C1fEv({{.*}}) unnamed_addr [[NUW:#[0-9]+]]<br>
 }<br>
<br>
+// Varargs non-covariant thunk test.<br>
+// PR18098<br>
+namespace Test15 {<br>
+  struct A {<br>
+    virtual ~A();<br>
+  };<br>
+  struct B {<br>
+    virtual void f(int x, ...);<br>
+  };<br>
+  struct C : A, B {<br>
+    virtual void c();<br>
+    virtual void f(int x, ...);<br>
+  };<br>
+  void C::c() {}<br>
+<br>
+  // C::c<br>
+  // CHECK: declare void @_ZN6Test151C1fEiz<br>
+  // non-virtual thunk to C::f<br>
+  // CHECK: declare void @_ZThn8_N6Test151C1fEiz<br>
+}<br>
+<br>
 /**** The following has to go at the end of the file ****/<br>
<br>
 // This is from Test5:<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>