[pkg-d-commits] [ldc] 36/211: Fix thunks naming so that extern(C++) matches C++ names

Matthias Klumpp mak at moszumanska.debian.org
Sun Apr 23 22:36:07 UTC 2017


This is an automated email from the git hooks/post-receive script.

mak pushed a commit to annotated tag v1.1.0
in repository ldc.

commit 9e99411b0be60fb8b8b3c5fcb29154faf35ac423
Author: Martin <noone at nowhere.com>
Date:   Wed Sep 21 19:06:56 2016 +0200

    Fix thunks naming so that extern(C++) matches C++ names
    
    E.g., for `extern(C++) int Derived::MethodCpp()`:
    `Th16_ZN7Derived9MethodCPPEv` => `_ZThn16_N7Derived9MethodCPPEv`
    
    This makes sure `runnable/cppa.d` and `runnable/extra-files/cppb.cpp` work
    when linking the 2 object files in any order on Linux, just as for DMD.
    
    Previously, it only worked if the C++ object was specified first. Then the
    C++ implementations of `Derived::MethodD()` and `Derived::Method()` were
    picked and the D ones discarded.
    If the C++ ones were discarded by specifying the D object first, the (C++)
    thunks in the (C++) interface vtable (i.e., used for `Derived` instances
    created on the C++ side) apparently got corrupted, jumping to null (as the
    thunk target, the real C++ function, got discarded in favor of the D one).
    
    By fixing the D thunk names, `extern(C++)` thunks are now overrideable as
    well. If the C++ object is specified first when linking, the C++ thunks
    (and methods) will be picked, otherwise the D thunks (and methods).
    So the interface vtables produced by C++ and D should now always point to
    the same set of thunks and thus resolve this nasty issue.
---
 ir/irclass.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/ir/irclass.cpp b/ir/irclass.cpp
index 5ca3375..6b4e9fa 100644
--- a/ir/irclass.cpp
+++ b/ir/irclass.cpp
@@ -298,7 +298,7 @@ llvm::GlobalVariable *IrAggr::getInterfaceVtbl(BaseClass *b, bool new_instance,
 
   // Thunk prefix
   char thunkPrefix[16];
-  int thunkLen = sprintf(thunkPrefix, "Th%d", b->offset);
+  int thunkLen = sprintf(thunkPrefix, "Thn%d_", b->offset);
   char thunkPrefixLen[16];
   sprintf(thunkPrefixLen, "%d", thunkLen);
 
@@ -338,8 +338,10 @@ llvm::GlobalVariable *IrAggr::getInterfaceVtbl(BaseClass *b, bool new_instance,
     // Create the thunk function if it does not already exist in this
     // module.
     OutBuffer nameBuf;
+    const auto mangledTargetName = mangleExact(fd);
+    nameBuf.write(mangledTargetName, 2);
     nameBuf.writestring(thunkPrefix);
-    nameBuf.writestring(mangleExact(fd));
+    nameBuf.writestring(mangledTargetName + 2);
     const char *thunkName = nameBuf.extractString();
     llvm::Function *thunk = gIR->module.getFunction(thunkName);
     if (!thunk) {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-d/ldc.git



More information about the pkg-d-commits mailing list