summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CGCall.cpp29
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp3
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h3
-rw-r--r--clang/test/CodeGenCXX/microsoft-abi-eh-inlineasm.cpp18
4 files changed, 37 insertions, 16 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index de42d159fa4..13b0c2ef253 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -3608,20 +3608,21 @@ CodeGenFunction::EmitRuntimeCall(llvm::Value *callee,
// Calls which may throw must have operand bundles indicating which funclet
// they are nested within.
-static void
-getBundlesForFunclet(llvm::Value *Callee, llvm::Instruction *CurrentFuncletPad,
- SmallVectorImpl<llvm::OperandBundleDef> &BundleList) {
+SmallVector<llvm::OperandBundleDef, 1>
+CodeGenFunction::getBundlesForFunclet(llvm::Value *Callee) {
+ SmallVector<llvm::OperandBundleDef, 1> BundleList;
// There is no need for a funclet operand bundle if we aren't inside a
// funclet.
if (!CurrentFuncletPad)
- return;
+ return BundleList;
// Skip intrinsics which cannot throw.
auto *CalleeFn = dyn_cast<llvm::Function>(Callee->stripPointerCasts());
if (CalleeFn && CalleeFn->isIntrinsic() && CalleeFn->doesNotThrow())
- return;
+ return BundleList;
BundleList.emplace_back("funclet", CurrentFuncletPad);
+ return BundleList;
}
/// Emits a simple call (never an invoke) to the given runtime function.
@@ -3629,10 +3630,8 @@ llvm::CallInst *
CodeGenFunction::EmitRuntimeCall(llvm::Value *callee,
ArrayRef<llvm::Value*> args,
const llvm::Twine &name) {
- SmallVector<llvm::OperandBundleDef, 1> BundleList;
- getBundlesForFunclet(callee, CurrentFuncletPad, BundleList);
-
- llvm::CallInst *call = Builder.CreateCall(callee, args, BundleList, name);
+ llvm::CallInst *call =
+ Builder.CreateCall(callee, args, getBundlesForFunclet(callee), name);
call->setCallingConv(getRuntimeCC());
return call;
}
@@ -3640,8 +3639,8 @@ CodeGenFunction::EmitRuntimeCall(llvm::Value *callee,
/// Emits a call or invoke to the given noreturn runtime function.
void CodeGenFunction::EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee,
ArrayRef<llvm::Value*> args) {
- SmallVector<llvm::OperandBundleDef, 1> BundleList;
- getBundlesForFunclet(callee, CurrentFuncletPad, BundleList);
+ SmallVector<llvm::OperandBundleDef, 1> BundleList =
+ getBundlesForFunclet(callee);
if (getInvokeDest()) {
llvm::InvokeInst *invoke =
@@ -3684,8 +3683,8 @@ CodeGenFunction::EmitCallOrInvoke(llvm::Value *Callee,
ArrayRef<llvm::Value *> Args,
const Twine &Name) {
llvm::BasicBlock *InvokeDest = getInvokeDest();
- SmallVector<llvm::OperandBundleDef, 1> BundleList;
- getBundlesForFunclet(Callee, CurrentFuncletPad, BundleList);
+ SmallVector<llvm::OperandBundleDef, 1> BundleList =
+ getBundlesForFunclet(Callee);
llvm::Instruction *Inst;
if (!InvokeDest)
@@ -4196,8 +4195,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
}
llvm::BasicBlock *InvokeDest = CannotThrow ? nullptr : getInvokeDest();
- SmallVector<llvm::OperandBundleDef, 1> BundleList;
- getBundlesForFunclet(CalleePtr, CurrentFuncletPad, BundleList);
+ SmallVector<llvm::OperandBundleDef, 1> BundleList =
+ getBundlesForFunclet(CalleePtr);
// Emit the actual call/invoke instruction.
llvm::CallSite CS;
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 12d136b0b9b..86c0964a857 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -2133,7 +2133,8 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
llvm::InlineAsm *IA =
llvm::InlineAsm::get(FTy, AsmString, Constraints, HasSideEffect,
/* IsAlignStack */ false, AsmDialect);
- llvm::CallInst *Result = Builder.CreateCall(IA, Args);
+ llvm::CallInst *Result =
+ Builder.CreateCall(IA, Args, getBundlesForFunclet(IA));
Result->addAttribute(llvm::AttributeList::FunctionIndex,
llvm::Attribute::NoUnwind);
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index e63220d1847..78335018936 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -3367,6 +3367,9 @@ public:
ArrayRef<llvm::Value*> args,
const Twine &name = "");
+ SmallVector<llvm::OperandBundleDef, 1>
+ getBundlesForFunclet(llvm::Value *Callee);
+
llvm::CallSite EmitCallOrInvoke(llvm::Value *Callee,
ArrayRef<llvm::Value *> Args,
const Twine &Name = "");
diff --git a/clang/test/CodeGenCXX/microsoft-abi-eh-inlineasm.cpp b/clang/test/CodeGenCXX/microsoft-abi-eh-inlineasm.cpp
new file mode 100644
index 00000000000..9d9bff75fd6
--- /dev/null
+++ b/clang/test/CodeGenCXX/microsoft-abi-eh-inlineasm.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-windows-msvc \
+// RUN: -fexceptions -fcxx-exceptions | FileCheck %s
+
+// Make sure calls to inline asm have funclet bundles.
+
+extern "C" void might_throw();
+extern "C" void foo() {
+ try {
+ might_throw();
+ } catch (int) {
+ __asm__("nop");
+ }
+}
+
+// CHECK-LABEL: define void @foo()
+// CHECK: invoke void @might_throw()
+// CHECK: %[[CATCHPAD:[^ ]*]] = catchpad within
+// CHECK: call void asm sideeffect "nop", {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
OpenPOWER on IntegriCloud