Add the 'noinline' attribute to call sites within __try bodies

LLVM doesn't support non-call exceptions, so inlining makes it harder to
catch such asynchronous exceptions.

llvm-svn: 228876
This commit is contained in:
Reid Kleckner 2015-02-11 21:40:48 +00:00
parent 59c8aa92b8
commit a593000f01
6 changed files with 25 additions and 6 deletions

View File

@ -3325,6 +3325,12 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
Attrs.addAttribute(getLLVMContext(), llvm::AttributeSet::FunctionIndex, Attrs.addAttribute(getLLVMContext(), llvm::AttributeSet::FunctionIndex,
llvm::Attribute::AlwaysInline); llvm::Attribute::AlwaysInline);
// Disable inlining inside SEH __try blocks.
if (IsSEHTryScope)
Attrs =
Attrs.addAttribute(getLLVMContext(), llvm::AttributeSet::FunctionIndex,
llvm::Attribute::NoInline);
CS.setAttributes(Attrs); CS.setAttributes(Attrs);
CS.setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv)); CS.setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));

View File

@ -21,6 +21,7 @@
#include "clang/AST/StmtObjC.h" #include "clang/AST/StmtObjC.h"
#include "llvm/IR/CallSite.h" #include "llvm/IR/CallSite.h"
#include "llvm/IR/Intrinsics.h" #include "llvm/IR/Intrinsics.h"
#include "llvm/Support/SaveAndRestore.h"
using namespace clang; using namespace clang;
using namespace CodeGen; using namespace CodeGen;
@ -1703,7 +1704,11 @@ void CodeGenFunction::EmitSEHTryStmt(const SEHTryStmt &S) {
SEHFinallyInfo FI; SEHFinallyInfo FI;
EnterSEHTryStmt(S, FI); EnterSEHTryStmt(S, FI);
EmitStmt(S.getTryBlock()); {
// Disable inlining inside SEH __try scopes.
SaveAndRestore<bool> Saver(IsSEHTryScope, true);
EmitStmt(S.getTryBlock());
}
ExitSEHTryStmt(S, FI); ExitSEHTryStmt(S, FI);
} }

View File

@ -40,7 +40,7 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
CurFn(nullptr), CapturedStmtInfo(nullptr), CurFn(nullptr), CapturedStmtInfo(nullptr),
SanOpts(CGM.getLangOpts().Sanitize), IsSanitizerScope(false), SanOpts(CGM.getLangOpts().Sanitize), IsSanitizerScope(false),
CurFuncIsThunk(false), AutoreleaseResult(false), SawAsmBlock(false), CurFuncIsThunk(false), AutoreleaseResult(false), SawAsmBlock(false),
BlockInfo(nullptr), BlockPointer(nullptr), IsSEHTryScope(false), BlockInfo(nullptr), BlockPointer(nullptr),
LambdaThisCaptureField(nullptr), NormalCleanupDest(nullptr), LambdaThisCaptureField(nullptr), NormalCleanupDest(nullptr),
NextCleanupDestIndex(1), FirstBlockInfo(nullptr), EHResumeBlock(nullptr), NextCleanupDestIndex(1), FirstBlockInfo(nullptr), EHResumeBlock(nullptr),
ExceptionSlot(nullptr), EHSelectorSlot(nullptr), ExceptionSlot(nullptr), EHSelectorSlot(nullptr),

View File

@ -263,6 +263,9 @@ public:
/// potentially set the return value. /// potentially set the return value.
bool SawAsmBlock; bool SawAsmBlock;
/// Codegen is currently inside an SEH try block.
bool IsSEHTryScope;
const CodeGen::CGBlockInfo *BlockInfo; const CodeGen::CGBlockInfo *BlockInfo;
llvm::Value *BlockPointer; llvm::Value *BlockPointer;

View File

@ -21,7 +21,7 @@ int safe_div(int numerator, int denominator, int *res) {
return success; return success;
} }
// CHECK-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res) // CHECK-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res)
// CHECK: invoke void @try_body(i32 %{{.*}}, i32 %{{.*}}, i32* %{{.*}}) // CHECK: invoke void @try_body(i32 %{{.*}}, i32 %{{.*}}, i32* %{{.*}}) #[[NOINLINE:[0-9]+]]
// CHECK: to label %{{.*}} unwind label %[[lpad:[^ ]*]] // CHECK: to label %{{.*}} unwind label %[[lpad:[^ ]*]]
// //
// CHECK: [[lpad]] // CHECK: [[lpad]]
@ -51,7 +51,7 @@ int filter_expr_capture(void) {
// CHECK-LABEL: define i32 @filter_expr_capture() // CHECK-LABEL: define i32 @filter_expr_capture()
// FIXMECHECK: %[[captures]] = call i8* @llvm.frameallocate(i32 4) // FIXMECHECK: %[[captures]] = call i8* @llvm.frameallocate(i32 4)
// CHECK: store i32 42, i32* %[[r:[^ ,]*]] // CHECK: store i32 42, i32* %[[r:[^ ,]*]]
// CHECK: invoke void @j() // CHECK: invoke void @j() #[[NOINLINE]]
// //
// CHECK: landingpad // CHECK: landingpad
// CHECK-NEXT: catch i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@filter_expr_capture@@" to i8*) // CHECK-NEXT: catch i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@filter_expr_capture@@" to i8*)
@ -81,7 +81,7 @@ int nested_try(void) {
} }
// CHECK-LABEL: define i32 @nested_try() // CHECK-LABEL: define i32 @nested_try()
// CHECK: store i32 42, i32* %[[r:[^ ,]*]] // CHECK: store i32 42, i32* %[[r:[^ ,]*]]
// CHECK: invoke void @j() // CHECK: invoke void @j() #[[NOINLINE]]
// CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
// //
// CHECK: [[cont]] // CHECK: [[cont]]
@ -179,3 +179,5 @@ int except_return(void) {
// CHECK: [[retbb]] // CHECK: [[retbb]]
// CHECK: %[[r:[^ ]*]] = load i32* %[[rv]] // CHECK: %[[r:[^ ]*]] = load i32* %[[rv]]
// CHECK: ret i32 %[[r]] // CHECK: ret i32 %[[r]]
// CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} }

View File

@ -58,7 +58,7 @@ extern "C" void use_seh() {
// Make sure we use __C_specific_handler for SEH. // Make sure we use __C_specific_handler for SEH.
// CHECK-LABEL: define void @use_seh() // CHECK-LABEL: define void @use_seh()
// CHECK: invoke void @might_throw() // CHECK: invoke void @might_throw() #[[NOINLINE:[0-9]+]]
// CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
// //
// CHECK: [[cont]] // CHECK: [[cont]]
@ -92,4 +92,7 @@ void use_seh_in_lambda() {
// NOCXX: ret void // NOCXX: ret void
// CHECK-LABEL: define internal void @"\01??R<lambda_0>@?use_seh_in_lambda@@YAXXZ@QEBAXXZ"(%class.anon* %this) // CHECK-LABEL: define internal void @"\01??R<lambda_0>@?use_seh_in_lambda@@YAXXZ@QEBAXXZ"(%class.anon* %this)
// CHECK: invoke void @might_throw() #[[NOINLINE]]
// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
// CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} }