[WinEH] Fix xdata generation when no catch object is present

The lack of a catch object is indicated by a frame escape index of -1.

Fixes PR23137.

llvm-svn: 234346
This commit is contained in:
Reid Kleckner 2015-04-07 19:46:38 +00:00
parent 39e20aa9c2
commit f1853c65d9
3 changed files with 66 additions and 6 deletions

View File

@ -263,7 +263,12 @@ namespace llvm {
MCSymbol *getOrCreateSectionSymbol(const MCSectionELF &Section);
/// Gets a symbol that will be defined to the final stack offset of a local
/// variable after codegen.
///
/// @param Idx - The index of a local variable passed to @llvm.frameescape.
MCSymbol *getOrCreateFrameAllocSymbol(StringRef FuncName, unsigned Idx);
MCSymbol *getOrCreateParentFrameOffsetSymbol(StringRef FuncName);
/// Get the symbol for \p Name, or null.

View File

@ -455,12 +455,20 @@ void Win64Exception::emitCXXFrameHandler3Table(const MachineFunction *MF) {
const MCSymbolRefExpr *ParentFrameOffsetRef = MCSymbolRefExpr::Create(
ParentFrameOffset, MCSymbolRefExpr::VK_None, Asm->OutContext);
MCSymbol *FrameAllocOffset =
Asm->OutContext.getOrCreateFrameAllocSymbol(
GlobalValue::getRealLinkageName(F->getName()),
HT.CatchObjRecoverIdx);
const MCSymbolRefExpr *FrameAllocOffsetRef = MCSymbolRefExpr::Create(
FrameAllocOffset, MCSymbolRefExpr::VK_None, Asm->OutContext);
// Get the frame escape label with the offset of the catch object. If
// the index is -1, then there is no catch object, and we should emit an
// offset of zero, indicating that no copy will occur.
const MCExpr *FrameAllocOffsetRef = nullptr;
if (HT.CatchObjRecoverIdx >= 0) {
MCSymbol *FrameAllocOffset =
Asm->OutContext.getOrCreateFrameAllocSymbol(
GlobalValue::getRealLinkageName(F->getName()),
HT.CatchObjRecoverIdx);
FrameAllocOffsetRef = MCSymbolRefExpr::Create(
FrameAllocOffset, MCSymbolRefExpr::VK_None, Asm->OutContext);
} else {
FrameAllocOffsetRef = MCConstantExpr::Create(0, Asm->OutContext);
}
OS.EmitIntValue(HT.Adjectives, 4); // Adjectives
OS.EmitValue(createImageRel32(HT.TypeDescriptor), 4); // Type

View File

@ -0,0 +1,47 @@
; RUN: llc < %s | FileCheck %s
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc"
; This test case is equivalent to:
; extern "C" void may_throw();
; extern "C" void test_catch_all() {
; try {
; may_throw();
; } catch (...) {
; }
; }
declare void @may_throw() #1
declare i32 @__CxxFrameHandler3(...)
declare void @llvm.eh.begincatch(i8* nocapture, i8* nocapture) #2
declare void @llvm.eh.endcatch() #2
; Function Attrs: nounwind uwtable
define void @test_catch_all() #0 {
entry:
invoke void @may_throw()
to label %try.cont unwind label %lpad
lpad: ; preds = %entry
%0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
catch i8* null
%1 = extractvalue { i8*, i32 } %0, 0
tail call void @llvm.eh.begincatch(i8* %1, i8* null) #2
tail call void @llvm.eh.endcatch() #2
br label %try.cont
try.cont: ; preds = %entry, %lpad
ret void
}
; CHECK-LABEL: $handlerMap$0$test_catch_all:
; CHECK: .long {{[0-9]+}}
; CHECK: .long 0
; CHECK: .long 0
; CHECK: .long test_catch_all.catch@IMGREL
; CHECK: .long .Ltest_catch_all.catch$parent_frame_offset
attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }