forked from OSchip/llvm-project
[SEH] Fix x64 __exception_code in __except blocks
Use llvm.eh.exceptioncode to get the code out of EAX for x64. For 32-bit, the filter is responsible for storing it to memory for us. llvm-svn: 249497
This commit is contained in:
parent
52dca345db
commit
f8d115338d
|
@ -1898,14 +1898,21 @@ void CodeGenFunction::ExitSEHTryStmt(const SEHTryStmt &S) {
|
|||
ExceptBB = createBasicBlock("__except");
|
||||
Builder.CreateCatchRet(CPI, ExceptBB);
|
||||
EmitBlock(ExceptBB);
|
||||
}
|
||||
|
||||
// On Win64, the exception pointer is the exception code. Copy it to the slot.
|
||||
if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
|
||||
llvm::Value *Code =
|
||||
Builder.CreatePtrToInt(getExceptionFromSlot(), IntPtrTy);
|
||||
Code = Builder.CreateTrunc(Code, Int32Ty);
|
||||
Builder.CreateStore(Code, SEHCodeSlotStack.back());
|
||||
// On Win64, the exception code is returned in EAX. Copy it into the slot.
|
||||
if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
|
||||
llvm::Function *SEHCodeIntrin =
|
||||
CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode);
|
||||
llvm::Value *Code = Builder.CreateCall(SEHCodeIntrin, {CPI});
|
||||
Builder.CreateStore(Code, SEHCodeSlotStack.back());
|
||||
}
|
||||
} else {
|
||||
// On Win64, the exception pointer is the exception code. Copy it to the slot.
|
||||
if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
|
||||
llvm::Value *Code =
|
||||
Builder.CreatePtrToInt(getExceptionFromSlot(), IntPtrTy);
|
||||
Code = Builder.CreateTrunc(Code, Int32Ty);
|
||||
Builder.CreateStore(Code, SEHCodeSlotStack.back());
|
||||
}
|
||||
}
|
||||
|
||||
// Emit the __except body.
|
||||
|
|
|
@ -265,4 +265,25 @@ void finally_capture_twice(int x) {
|
|||
// CHECK-NEXT: store i32 [[T0]], i32* [[Z]], align 4
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
int exception_code_in_except(void) {
|
||||
__try {
|
||||
try_body(0, 0, 0);
|
||||
} __except(1) {
|
||||
return _exception_code();
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define i32 @exception_code_in_except()
|
||||
// CHECK: %[[ret_slot:[^ ]*]] = alloca i32
|
||||
// CHECK: %[[code_slot:[^ ]*]] = alloca i32
|
||||
// CHECK: invoke void @try_body(i32 0, i32 0, i32* null)
|
||||
// CHECK: %[[pad:[^ ]*]] = catchpad
|
||||
// CHECK: catchret %[[pad]]
|
||||
// X64: %[[code:[^ ]*]] = call i32 @llvm.eh.exceptioncode(token %[[pad]])
|
||||
// X64: store i32 %[[code]], i32* %[[code_slot]]
|
||||
// CHECK: %[[ret1:[^ ]*]] = load i32, i32* %[[code_slot]]
|
||||
// CHECK: store i32 %[[ret1]], i32* %[[ret_slot]]
|
||||
// CHECK: %[[ret2:[^ ]*]] = load i32, i32* %[[ret_slot]]
|
||||
// CHECK: ret i32 %[[ret2]]
|
||||
|
||||
// CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} }
|
||||
|
|
Loading…
Reference in New Issue