Index: lib/CodeGen/AsmPrinter/WinException.cpp =================================================================== --- lib/CodeGen/AsmPrinter/WinException.cpp +++ lib/CodeGen/AsmPrinter/WinException.cpp @@ -38,6 +38,23 @@ #include "llvm/Target/TargetOptions.h" using namespace llvm; +static std::string GetNameFromFunction(llvm::Function const& F) { + std::string name; + if(F.hasName()) + name = F.getName(); + else + name = std::to_string( + std::distance( + F.getParent()->begin(), + std::find_if( + F.getParent()->begin(), + F.getParent()->end(), + [&F](Function const& Fun){return &Fun == &F;}) + ) + ); + return GlobalValue::dropLLVMManglingEscape(name); +} + WinException::WinException(AsmPrinter *A) : EHStreamer(A) { // MSVC's EH tables are always composed of 32-bit words. All known 64-bit // platforms use an imagerel32 relocation to refer to symbols. @@ -97,8 +114,7 @@ // make sure we emit the parent offset label. Some unreferenced filter // functions may still refer to it. const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo(); - StringRef FLinkageName = - GlobalValue::dropLLVMManglingEscape(MF->getFunction().getName()); + std::string FLinkageName = GetNameFromFunction(MF->getFunction()); emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName); } shouldEmitLSDA = hasEHFunclets; @@ -171,7 +187,7 @@ // their funclet entry block's number. const MachineFunction *MF = MBB->getParent(); const Function &F = MF->getFunction(); - StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName()); + std::string FuncLinkageName = GetNameFromFunction(F); MCContext &Ctx = MF->getContext(); StringRef HandlerPrefix = MBB->isCleanupFuncletEntry() ? "dtor" : "catch"; return Ctx.getOrCreateSymbol("?" + HandlerPrefix + "$" + @@ -249,7 +265,7 @@ !CurrentFuncletEntry->isCleanupFuncletEntry()) { // If this is a C++ catch funclet (or the parent function), // emit a reference to the LSDA for the parent function. - StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName()); + std::string FuncLinkageName = GetNameFromFunction(F); MCSymbol *FuncInfoXData = Asm->OutContext.getOrCreateSymbol( Twine("$cppxdata$", FuncLinkageName)); Asm->OutStreamer->EmitValue(create32bitRef(FuncInfoXData), 4); @@ -532,8 +548,7 @@ // Emit a label assignment with the SEH frame offset so we can use it for // llvm.x86.seh.recoverfp. - StringRef FLinkageName = - GlobalValue::dropLLVMManglingEscape(MF->getFunction().getName()); + std::string FLinkageName = GetNameFromFunction(MF->getFunction()); MCSymbol *ParentFrameOffset = Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName); const MCExpr *MCOffset = @@ -632,7 +647,7 @@ auto &OS = *Asm->OutStreamer; const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo(); - StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName()); + std::string FuncLinkageName = GetNameFromFunction(F); SmallVector, 4> IPToStateTable; MCSymbol *FuncInfoXData = nullptr; @@ -939,7 +954,7 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) { MCStreamer &OS = *Asm->OutStreamer; const Function &F = MF->getFunction(); - StringRef FLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName()); + std::string FLinkageName = GetNameFromFunction(F); bool VerboseAsm = OS.isVerboseAsm(); auto AddComment = [&](const Twine &Comment) { Index: test/CodeGen/WinEH/wineh-unnamed.ll =================================================================== --- /dev/null +++ test/CodeGen/WinEH/wineh-unnamed.ll @@ -0,0 +1,102 @@ +; Check we can compile winEH file with unnamed functions without collision on +; funclet symbol name. +; We can improve this test and run it to see that generated program crash but +; it will only work on windows targets +; RUN: llc < %s + +; ModuleID = 'wineh-unnamed.ll' +source_filename = "C:\5CUsers\5Cvagrant\5CDesktop\5Ctest.cpp" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%rtti.TypeDescriptor5 = type { i8**, i8*, [6 x i8] } +%eh.CatchableType = type { i32, i32, i32, i32, i32, i32, i32 } +%eh.CatchableTypeArray.2 = type { i32, [2 x i32] } +%eh.ThrowInfo = type { i32, i32, i32, i32 } + +$"\01??_C@_03JIDPIAJI@err?$AA@" = comdat any + +$"\01??_R0PEAD@8" = comdat any + +$"_CT??_R0PEAD@88" = comdat any + +$"\01??_R0PEAX@8" = comdat any + +$"_CT??_R0PEAX@88" = comdat any + +$_CTA2PEAD = comdat any + +$_TIC2PEAD = comdat any + +@"\01??_C@_03JIDPIAJI@err?$AA@" = linkonce_odr unnamed_addr constant [4 x i8] c"err\00", comdat, align 1 +@"\01??_7type_info@@6B@" = external constant i8* +@"\01??_R0PEAD@8" = linkonce_odr global %rtti.TypeDescriptor5 { i8** @"\01??_7type_info@@6B@", i8* null, [6 x i8] c".PEAD\00" }, comdat +@__ImageBase = external constant i8 +@"_CT??_R0PEAD@88" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor5* @"\01??_R0PEAD@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 -1, i32 0, i32 8, i32 0 }, section ".xdata", comdat +@"\01??_R0PEAX@8" = linkonce_odr global %rtti.TypeDescriptor5 { i8** @"\01??_7type_info@@6B@", i8* null, [6 x i8] c".PEAX\00" }, comdat +@"_CT??_R0PEAX@88" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor5* @"\01??_R0PEAX@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 -1, i32 0, i32 8, i32 0 }, section ".xdata", comdat +@_CTA2PEAD = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.2 { i32 2, [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%eh.CatchableType* @"_CT??_R0PEAD@88" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%eh.CatchableType* @"_CT??_R0PEAX@88" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32)] }, section ".xdata", comdat +@_TIC2PEAD = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%eh.CatchableTypeArray.2* @_CTA2PEAD to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, section ".xdata", comdat + +define void @"\01?raise@@YAXH@Z"(i32 %i) local_unnamed_addr { +entry: + %tmp = alloca i8*, align 8 + %cmp = icmp eq i32 %i, 1 + br i1 %cmp, label %if.then, label %if.end + +if.then: + store i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"\01??_C@_03JIDPIAJI@err?$AA@", i64 0, i64 0), i8** %tmp, align 8 + %0 = bitcast i8** %tmp to i8* + call void @_CxxThrowException(i8* nonnull %0, %eh.ThrowInfo* nonnull @_TIC2PEAD) + unreachable + +if.end: + ret void +} + +declare dllimport void @_CxxThrowException(i8*, %eh.ThrowInfo*) local_unnamed_addr + +define internal fastcc i32 @0(i32 %i) unnamed_addr personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { +entry: + invoke void @"\01?raise@@YAXH@Z"(i32 %i) + to label %return unwind label %catch.dispatch + +catch.dispatch: + %0 = catchswitch within none [label %catch] unwind to caller + +catch: + %1 = catchpad within %0 [i8* null, i32 64, i8* null] + catchret from %1 to label %return + +return: + %retval.0 = phi i32 [ 1, %catch ], [ 0, %entry ] + ret i32 %retval.0 +} + +declare i32 @__CxxFrameHandler3(...) + +define internal fastcc i32 @1(i32 %i) unnamed_addr personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { +entry: + %add = add nsw i32 %i, -1 + invoke void @"\01?raise@@YAXH@Z"(i32 %add) + to label %return unwind label %catch.dispatch + +catch.dispatch: + %0 = catchswitch within none [label %catch] unwind to caller + +catch: + %1 = catchpad within %0 [i8* null, i32 64, i8* null] + catchret from %1 to label %return + +return: + %retval.0 = phi i32 [ 4, %catch ], [ 2, %entry ] + ret i32 %retval.0 +} + +define i32 @main(i32 %argc) local_unnamed_addr { +entry: + %call = tail call fastcc i32 @0(i32 %argc) + %call1 = tail call fastcc i32 @1(i32 %argc) + %add = add nsw i32 %call1, %call + ret i32 %add +}