Skip to content

Commit

Permalink
Differentiate C++ catch clauses from D ones by wrapping std::type_inf…
Browse files Browse the repository at this point in the history
…o pointers inside __cpp_type_info_ptr class instances like DMD does.

Previously assuming in the personality routine that encountering a C++ exception meant that catch clauses were raw std::type_info pointers was wrong in cases like:

try {
   throwStdException(); // external C++ function throwing a std::exception
} catch (Throwable t) {
   (...)
}

Generated __cpp_type_info_ptr constants receive the same mangling that they do within DMD.
  • Loading branch information
Syniurge committed Feb 21, 2018
1 parent 13e3cf5 commit 893890d
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
22 changes: 21 additions & 1 deletion gen/trycatchfinally.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
#include "gen/funcgenstate.h"
#include "gen/llvmhelpers.h"
#include "gen/ms-cxx-helper.h"
#include "gen/rttibuilder.h"
#include "gen/runtime.h"
#include "gen/tollvm.h"
#include "ir/irfunction.h"
#include "ir/irtypeclass.h"

////////////////////////////////////////////////////////////////////////////////

Expand Down Expand Up @@ -159,9 +161,27 @@ void TryCatchScope::emitCatchBodies(IRState &irs, llvm::Value *ehPtrSlot) {
LLGlobalVariable *ci;
if (p.cd->isCPPclass()) {
const char *name = Target::cppTypeInfoMangle(p.cd);
ci = getOrCreateGlobal(
auto cpp_ti = getOrCreateGlobal(
p.cd->loc, irs.module, getVoidPtrType(), /*isConstant=*/true,
LLGlobalValue::ExternalLinkage, /*init=*/nullptr, name);

// Wrap std::type_info pointers inside a __cpp_type_info_ptr class instance so that
// the personality routine may differentiate C++ catch clauses from D ones.
OutBuffer mangleBuf;
mangleBuf.writestring("_D");
mangleToBuffer(p.cd, &mangleBuf);
mangleBuf.printf("%d%s", 18, "_cpp_type_info_ptr");

RTTIBuilder b(ClassDeclaration::cpp_type_info_ptr);
b.push(cpp_ti);

auto wrapperType = llvm::cast<llvm::StructType>(
static_cast<IrTypeClass*>(ClassDeclaration::cpp_type_info_ptr->type->ctype)->getMemoryLLType());
auto wrapperInit = b.get_constant(wrapperType);

ci = getOrCreateGlobal(
p.cd->loc, irs.module, wrapperType, /*isConstant=*/true,
LLGlobalValue::LinkOnceODRLinkage, wrapperInit, mangleBuf.peekString());
} else {
ci = getIrAggr(p.cd)->getClassInfoSymbol();
}
Expand Down
2 changes: 1 addition & 1 deletion runtime/druntime
Submodule druntime updated 1 files
+4 −25 src/rt/dwarfeh.d

0 comments on commit 893890d

Please sign in to comment.