[SEH] Use the SEH personality on frontend-outlined funclets

This allows __try inside __finally to work.

Fixes PR34939

llvm-svn: 315707
This commit is contained in:
Reid Kleckner 2017-10-13 16:55:14 +00:00
parent df9611e178
commit 65fa869c23
2 changed files with 27 additions and 1 deletions

View File

@ -225,7 +225,12 @@ const EHPersonality &EHPersonality::get(CodeGenModule &CGM,
}
const EHPersonality &EHPersonality::get(CodeGenFunction &CGF) {
return get(CGF.CGM, dyn_cast_or_null<FunctionDecl>(CGF.CurCodeDecl));
const auto *FD = CGF.CurCodeDecl;
// For outlined finallys and filters, use the SEH personality in case they
// contain more SEH. This mostly only affects finallys. Filters could
// hypothetically use gnu statement expressions to sneak in nested SEH.
FD = FD ? FD : CGF.CurSEHParent;
return get(CGF.CGM, dyn_cast_or_null<FunctionDecl>(FD));
}
static llvm::Constant *getPersonalityFn(CodeGenModule &CGM,

View File

@ -76,6 +76,27 @@ extern "C" void use_seh() {
// CHECK: [[cont]]
// CHECK: br label %[[ret]]
extern "C" void nested_finally() {
__try {
might_throw();
} __finally {
__try {
might_throw();
} __finally {
}
}
}
// CHECK-LABEL: define void @nested_finally() #{{[0-9]+}}
// CHECK-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
// CHECK: invoke void @might_throw()
// CHECK: call void @"\01?fin$0@0@nested_finally@@"(i8 1, i8* {{.*}})
// CHECK-LABEL: define internal void @"\01?fin$0@0@nested_finally@@"
// CHECK-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
// CHECK: invoke void @might_throw()
// CHECK: call void @"\01?fin$1@0@nested_finally@@"(i8 1, i8* {{.*}})
void use_seh_in_lambda() {
([]() {
__try {