diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGException.cpp | 7 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 3 | ||||
-rw-r--r-- | clang/test/CodeGen/exceptions-seh.c | 8 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/exceptions-seh.cpp | 5 |
6 files changed, 25 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 0574a1a34dc..60ab2effbeb 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -3325,6 +3325,12 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, Attrs.addAttribute(getLLVMContext(), llvm::AttributeSet::FunctionIndex, 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.setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv)); diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index 9df4f977318..b8ce205ff1b 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -21,6 +21,7 @@ #include "clang/AST/StmtObjC.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/Support/SaveAndRestore.h" using namespace clang; using namespace CodeGen; @@ -1703,7 +1704,11 @@ void CodeGenFunction::EmitSEHTryStmt(const SEHTryStmt &S) { SEHFinallyInfo FI; EnterSEHTryStmt(S, FI); - EmitStmt(S.getTryBlock()); + { + // Disable inlining inside SEH __try scopes. + SaveAndRestore<bool> Saver(IsSEHTryScope, true); + EmitStmt(S.getTryBlock()); + } ExitSEHTryStmt(S, FI); } diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 79425d4c21e..43dd7a05de1 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -40,7 +40,7 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext) CurFn(nullptr), CapturedStmtInfo(nullptr), SanOpts(CGM.getLangOpts().Sanitize), IsSanitizerScope(false), CurFuncIsThunk(false), AutoreleaseResult(false), SawAsmBlock(false), - BlockInfo(nullptr), BlockPointer(nullptr), + IsSEHTryScope(false), BlockInfo(nullptr), BlockPointer(nullptr), LambdaThisCaptureField(nullptr), NormalCleanupDest(nullptr), NextCleanupDestIndex(1), FirstBlockInfo(nullptr), EHResumeBlock(nullptr), ExceptionSlot(nullptr), EHSelectorSlot(nullptr), diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 998e0676cd2..6011333c9dd 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -263,6 +263,9 @@ public: /// potentially set the return value. bool SawAsmBlock; + /// Codegen is currently inside an SEH try block. + bool IsSEHTryScope; + const CodeGen::CGBlockInfo *BlockInfo; llvm::Value *BlockPointer; diff --git a/clang/test/CodeGen/exceptions-seh.c b/clang/test/CodeGen/exceptions-seh.c index 98b9de5d59d..ebe97bedd23 100644 --- a/clang/test/CodeGen/exceptions-seh.c +++ b/clang/test/CodeGen/exceptions-seh.c @@ -21,7 +21,7 @@ int safe_div(int numerator, int denominator, int *res) { return success; } // 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: [[lpad]] @@ -51,7 +51,7 @@ int filter_expr_capture(void) { // CHECK-LABEL: define i32 @filter_expr_capture() // FIXMECHECK: %[[captures]] = call i8* @llvm.frameallocate(i32 4) // CHECK: store i32 42, i32* %[[r:[^ ,]*]] -// CHECK: invoke void @j() +// CHECK: invoke void @j() #[[NOINLINE]] // // CHECK: landingpad // 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: store i32 42, i32* %[[r:[^ ,]*]] -// CHECK: invoke void @j() +// CHECK: invoke void @j() #[[NOINLINE]] // CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // // CHECK: [[cont]] @@ -179,3 +179,5 @@ int except_return(void) { // CHECK: [[retbb]] // CHECK: %[[r:[^ ]*]] = load i32* %[[rv]] // CHECK: ret i32 %[[r]] + +// CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} } diff --git a/clang/test/CodeGenCXX/exceptions-seh.cpp b/clang/test/CodeGenCXX/exceptions-seh.cpp index 38d176b829f..5f93cb1be3f 100644 --- a/clang/test/CodeGenCXX/exceptions-seh.cpp +++ b/clang/test/CodeGenCXX/exceptions-seh.cpp @@ -58,7 +58,7 @@ extern "C" void use_seh() { // Make sure we use __C_specific_handler for 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: [[cont]] @@ -92,4 +92,7 @@ void use_seh_in_lambda() { // NOCXX: ret void // 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: attributes #[[NOINLINE]] = { {{.*noinline.*}} } |