summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CGException.cpp113
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp5
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h12
-rw-r--r--clang/test/CXX/except/except.spec/p9-dynamic.cpp5
-rw-r--r--clang/test/CXX/except/except.spec/p9-noexcept.cpp3
-rw-r--r--clang/test/CodeGen/exceptions.c6
-rw-r--r--clang/test/CodeGenCXX/arm.cpp10
-rw-r--r--clang/test/CodeGenCXX/destructors.cpp10
-rw-r--r--clang/test/CodeGenCXX/dynamic-cast.cpp3
-rw-r--r--clang/test/CodeGenCXX/eh.cpp17
-rw-r--r--clang/test/CodeGenCXX/nrvo.cpp13
-rw-r--r--clang/test/CodeGenCXX/partial-destruction.cpp18
-rw-r--r--clang/test/CodeGenCXX/threadsafe-statics-exceptions.cpp7
-rw-r--r--clang/test/CodeGenCXX/typeid.cpp3
-rw-r--r--clang/test/CodeGenObjC/blocks-2.m5
-rw-r--r--clang/test/CodeGenObjC/gnu-exceptions.m6
-rw-r--r--clang/test/CodeGenObjC/terminate.m8
-rw-r--r--clang/test/CodeGenObjCXX/catch-id-type.mm5
-rw-r--r--clang/test/CodeGenObjCXX/exceptions.mm3
19 files changed, 138 insertions, 114 deletions
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index e7119149557..14a89cff3f9 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -306,12 +306,6 @@ static llvm::Constant *getCatchAllValue(CodeGenFunction &CGF) {
return llvm::ConstantPointerNull::get(CGF.Int8PtrTy);
}
-/// Returns the value to inject into a selector to indicate the
-/// presence of a cleanup.
-static llvm::Constant *getCleanupValue(CodeGenFunction &CGF) {
- return llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
-}
-
namespace {
/// A cleanup to free the exception object if its initialization
/// throws.
@@ -733,17 +727,19 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
llvm::BasicBlock *lpad = createBasicBlock("lpad");
EmitBlock(lpad);
+ llvm::LandingPadInst *LPadInst =
+ Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty, NULL),
+ getOpaquePersonalityFn(CGM, personality), 0);
+
+ llvm::Value *LPadExn = Builder.CreateExtractValue(LPadInst, 0);
+ Builder.CreateStore(LPadExn, getExceptionSlot());
+ llvm::Value *LPadSel = Builder.CreateExtractValue(LPadInst, 1);
+ Builder.CreateStore(LPadSel, getEHSelectorSlot());
+
// Save the exception pointer. It's safe to use a single exception
// pointer per function because EH cleanups can never have nested
// try/catches.
- llvm::CallInst *exn =
- Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_exception), "exn");
- exn->setDoesNotThrow();
-
- // Build the selector arguments.
- SmallVector<llvm::Value*, 8> selector;
- selector.push_back(exn);
- selector.push_back(getOpaquePersonalityFn(CGM, personality));
+ // Build the landingpad instruction.
// Accumulate all the handlers in scope.
bool hasCatchAll = false;
@@ -764,7 +760,7 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
assert(I.next() == EHStack.end() && "EH filter is not end of EH stack");
assert(!hasCatchAll && "EH filter reached after catch-all");
- // Filter scopes get added to the selector in weird ways.
+ // Filter scopes get added to the landingpad in weird ways.
EHFilterScope &filter = cast<EHFilterScope>(*I);
hasFilter = true;
@@ -800,54 +796,52 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
}
// Check whether we already have a handler for this type.
- if (catchTypes.insert(handler.Type)) {
- // If not, add it directly to the selector.
- selector.push_back(handler.Type);
- }
+ if (catchTypes.insert(handler.Type))
+ // If not, add it directly to the landingpad.
+ LPadInst->addClause(handler.Type);
}
}
done:
- // If we have a catch-all, add null to the selector.
+ // If we have a catch-all, add null to the landingpad.
assert(!(hasCatchAll && hasFilter));
if (hasCatchAll) {
- selector.push_back(getCatchAllValue(*this));
+ LPadInst->addClause(getCatchAllValue(*this));
// If we have an EH filter, we need to add those handlers in the
- // right place in the selector, which is to say, at the end.
+ // right place in the landingpad, which is to say, at the end.
} else if (hasFilter) {
// Create a filter expression: an integer constant saying how many
// filters there are (+1 to avoid ambiguity with 0 for cleanup),
// followed by the filter types. The personality routine only
// lands here if the filter doesn't match.
- selector.push_back(Builder.getInt32(filterTypes.size() + 1));
- selector.append(filterTypes.begin(), filterTypes.end());
+ llvm::SmallVector<llvm::Constant*, 8> Filters;
+ llvm::ArrayType *AType =
+ llvm::ArrayType::get(!filterTypes.empty() ?
+ filterTypes[0]->getType() : Int8PtrTy,
+ filterTypes.size());
+
+ for (unsigned i = 0, e = filterTypes.size(); i != e; ++i)
+ Filters.push_back(cast<llvm::Constant>(filterTypes[i]));
+ llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
+ LPadInst->addClause(FilterArray);
// Also check whether we need a cleanup.
- if (CleanupHackLevel == CHL_MandatoryCatchall || hasCleanup)
- selector.push_back(CleanupHackLevel == CHL_MandatoryCatchall
- ? getCatchAllValue(*this)
- : getCleanupValue(*this));
+ if (hasCleanup)
+ LPadInst->setCleanup(true);
// Otherwise, signal that we at least have cleanups.
} else if (CleanupHackLevel == CHL_MandatoryCatchall || hasCleanup) {
- selector.push_back(CleanupHackLevel == CHL_MandatoryCatchall
- ? getCatchAllValue(*this)
- : getCleanupValue(*this));
+ if (CleanupHackLevel == CHL_MandatoryCatchall)
+ LPadInst->addClause(getCatchAllValue(*this));
+ else
+ LPadInst->setCleanup(true);
}
- assert(selector.size() >= 3 && "selector call has only two arguments!");
+ assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
+ "landingpad instruction has no clauses!");
// Tell the backend how to generate the landing pad.
- llvm::CallInst *selectorCall =
- Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_selector),
- selector, "eh.selector");
- selectorCall->setDoesNotThrow();
-
- // Save the selector and exception pointer.
- Builder.CreateStore(exn, getExceptionSlot());
- Builder.CreateStore(selectorCall, getEHSelectorSlot());
-
Builder.CreateBr(getEHDispatchBlock(EHStack.getInnermostEHScope()));
// Restore the old IR generation state.
@@ -1462,19 +1456,11 @@ llvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() {
Builder.SetInsertPoint(TerminateLandingPad);
// Tell the backend that this is a landing pad.
- llvm::CallInst *Exn =
- Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_exception), "exn");
- Exn->setDoesNotThrow();
-
const EHPersonality &Personality = EHPersonality::get(CGM.getLangOptions());
-
- // Tell the backend what the exception table should be:
- // nothing but a catch-all.
- llvm::Value *Args[3] = { Exn, getOpaquePersonalityFn(CGM, Personality),
- getCatchAllValue(*this) };
- Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_selector),
- Args, "eh.selector")
- ->setDoesNotThrow();
+ llvm::LandingPadInst *LPadInst =
+ Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty, NULL),
+ getOpaquePersonalityFn(CGM, Personality), 0);
+ LPadInst->addClause(getCatchAllValue(*this));
llvm::CallInst *TerminateCall = Builder.CreateCall(getTerminateFn(*this));
TerminateCall->setDoesNotReturn();
@@ -1538,12 +1524,21 @@ llvm::BasicBlock *CodeGenFunction::getEHResumeBlock() {
->setDoesNotReturn();
break;
case CHL_MandatoryCleanup: {
- // In mandatory-cleanup mode, we should use llvm.eh.resume.
- llvm::Value *Selector = getSelectorFromSlot();
- Builder.CreateCall2(CGM.getIntrinsic(llvm::Intrinsic::eh_resume),
- Exn, Selector)
- ->setDoesNotReturn();
- break;
+ // In mandatory-cleanup mode, we should use 'resume'.
+
+ // Recreate the landingpad's return value for the 'resume' instruction.
+ llvm::Value *Exn = getExceptionFromSlot();
+ llvm::Value *Sel = getSelectorFromSlot();
+
+ llvm::Type *LPadType = llvm::StructType::get(Exn->getType(),
+ Sel->getType(), NULL);
+ llvm::Value *LPadVal = llvm::UndefValue::get(LPadType);
+ LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0, "lpad.val");
+ LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1, "lpad.val");
+
+ Builder.CreateResume(LPadVal);
+ Builder.restoreIP(SavedIP);
+ return EHResumeBlock;
}
case CHL_Ideal:
// In an idealized mode where we don't have to worry about the
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index b4b2eb16ada..d38a9b0859a 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -365,9 +365,12 @@ static void TryMarkNoThrow(llvm::Function *F) {
for (llvm::Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
for (llvm::BasicBlock::iterator
BI = FI->begin(), BE = FI->end(); BI != BE; ++BI)
- if (llvm::CallInst *Call = dyn_cast<llvm::CallInst>(&*BI))
+ if (llvm::CallInst *Call = dyn_cast<llvm::CallInst>(&*BI)) {
if (!Call->doesNotThrow())
return;
+ } else if (isa<llvm::ResumeInst>(&*BI)) {
+ return;
+ }
F->setDoesNotThrow(true);
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 177e647b4d1..19541a97673 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -612,12 +612,12 @@ public:
/// EHResumeBlock - Unified block containing a call to llvm.eh.resume.
llvm::BasicBlock *EHResumeBlock;
- /// The exception slot. All landing pads write the current
- /// exception pointer into this alloca.
+ /// The exception slot. All landing pads write the current exception pointer
+ /// into this alloca.
llvm::Value *ExceptionSlot;
- /// The selector slot. Under the MandatoryCleanup model, all
- /// landing pads write the current selector value into this alloca.
+ /// The selector slot. Under the MandatoryCleanup model, all landing pads
+ /// write the current selector value into this alloca.
llvm::AllocaInst *EHSelectorSlot;
/// Emits a landing pad for the current EH stack.
@@ -1116,8 +1116,8 @@ public:
const LangOptions &getLangOptions() const { return CGM.getLangOptions(); }
- /// Returns a pointer to the function's exception object slot, which
- /// is assigned in every landing pad.
+ /// Returns a pointer to the function's exception object and selector slot,
+ /// which is assigned in every landing pad.
llvm::Value *getExceptionSlot();
llvm::Value *getEHSelectorSlot();
diff --git a/clang/test/CXX/except/except.spec/p9-dynamic.cpp b/clang/test/CXX/except/except.spec/p9-dynamic.cpp
index 3f496f25c9b..4559e0d467b 100644
--- a/clang/test/CXX/except/except.spec/p9-dynamic.cpp
+++ b/clang/test/CXX/except/except.spec/p9-dynamic.cpp
@@ -7,5 +7,6 @@ void target() throw(int)
// CHECK: invoke void @_Z8externalv()
external();
}
-// CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} i8* bitcast (i8** @_ZTIi to i8*)) nounwind
-// CHECK: call void @__cxa_call_unexpected
+// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+// CHECK-NEXT: filter [1 x i8*] [i8* bitcast (i8** @_ZTIi to i8*)]
+// CHECK: call void @__cxa_call_unexpected
diff --git a/clang/test/CXX/except/except.spec/p9-noexcept.cpp b/clang/test/CXX/except/except.spec/p9-noexcept.cpp
index 76ac66c841b..7b2a259e195 100644
--- a/clang/test/CXX/except/except.spec/p9-noexcept.cpp
+++ b/clang/test/CXX/except/except.spec/p9-noexcept.cpp
@@ -7,7 +7,8 @@ void target() noexcept
// CHECK: invoke void @_Z8externalv()
external();
}
-// CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} i8* null) nounwind
+// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+// CHECK-NEXT: catch i8* null
// CHECK-NEXT: call void @_ZSt9terminatev() noreturn nounwind
// CHECK-NEXT: unreachable
diff --git a/clang/test/CodeGen/exceptions.c b/clang/test/CodeGen/exceptions.c
index 018b975395b..20eb706a03b 100644
--- a/clang/test/CodeGen/exceptions.c
+++ b/clang/test/CodeGen/exceptions.c
@@ -14,6 +14,8 @@ void test1() {
// CHECK-ARM: invoke arm_aapcscc void @test1_helper(
test1_helper(^(int v) { x = v; });
- // CHECK: call {{.*}} @llvm.eh.selector({{.*}}, i8* bitcast (i32 (...)* @__gcc_personality_v0 to i8*)
- // CHECK-ARM: call {{.*}} @llvm.eh.selector({{.*}}, i8* bitcast (i32 (...)* @__gcc_personality_sj0 to i8*)
+ // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gcc_personality_v0 to i8*)
+ // CHECK-NEXT: cleanup
+ // CHECK-ARM: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gcc_personality_sj0 to i8*)
+ // CHECK-ARM-NEXT: cleanup
}
diff --git a/clang/test/CodeGenCXX/arm.cpp b/clang/test/CodeGenCXX/arm.cpp
index dcb27ce0dab..a767f425553 100644
--- a/clang/test/CodeGenCXX/arm.cpp
+++ b/clang/test/CodeGenCXX/arm.cpp
@@ -308,9 +308,10 @@ namespace test7 {
// CHECK: ret void
static int x = foo();
- // CHECK: call i8* @llvm.eh.exception()
+ // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK-NEXT: cleanup
// CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test74testEvE1x)
- // CHECK: call void @llvm.eh.resume(
+ // CHECK: resume { i8*, i32 }
}
}
@@ -347,9 +348,10 @@ namespace test8 {
// CHECK: ret void
static A x;
- // CHECK: call i8* @llvm.eh.exception()
+ // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK-NEXT: cleanup
// CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test84testEvE1x)
- // CHECK: call void @llvm.eh.resume(
+ // CHECK: resume { i8*, i32 }
}
}
diff --git a/clang/test/CodeGenCXX/destructors.cpp b/clang/test/CodeGenCXX/destructors.cpp
index dc24551a593..d9962e615ec 100644
--- a/clang/test/CodeGenCXX/destructors.cpp
+++ b/clang/test/CodeGenCXX/destructors.cpp
@@ -356,9 +356,10 @@ namespace test8 {
// CHECK: invoke void @_ZN5test312_GLOBAL__N_11DD1Ev(
// CHECK: call void @_ZdlPv({{.*}}) nounwind
// CHECK: ret void
- // CHECK: call i8* @llvm.eh.exception(
+ // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK-NEXT: cleanup
// CHECK: call void @_ZdlPv({{.*}}) nounwind
- // CHECK: call void @llvm.eh.resume(
+ // CHECK: resume { i8*, i32 }
// Checked at top of file:
// @_ZN5test312_GLOBAL__N_11DD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11DD2Ev
@@ -386,9 +387,10 @@ namespace test8 {
// CHECK: invoke void @_ZN5test312_GLOBAL__N_11CD1Ev(
// CHECK: call void @_ZdlPv({{.*}}) nounwind
// CHECK: ret void
- // CHECK: call i8* @llvm.eh.exception()
+ // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK-NEXT: cleanup
// CHECK: call void @_ZdlPv({{.*}}) nounwind
- // CHECK: call void @llvm.eh.resume(
+ // CHECK: resume { i8*, i32 }
// CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD1Ev(
// CHECK: getelementptr inbounds i8* {{.*}}, i64 -8
diff --git a/clang/test/CodeGenCXX/dynamic-cast.cpp b/clang/test/CodeGenCXX/dynamic-cast.cpp
index e84bb9b4ff5..813e36e941b 100644
--- a/clang/test/CodeGenCXX/dynamic-cast.cpp
+++ b/clang/test/CodeGenCXX/dynamic-cast.cpp
@@ -11,7 +11,8 @@ const B& f(A *a) {
// CHECK: invoke void @__cxa_bad_cast() noreturn
dynamic_cast<const B&>(*a);
} catch (...) {
- // CHECK: call i8* @llvm.eh.exception
+ // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK-NEXT: catch i8* null
}
return fail;
}
diff --git a/clang/test/CodeGenCXX/eh.cpp b/clang/test/CodeGenCXX/eh.cpp
index 24807d92d70..e9909942479 100644
--- a/clang/test/CodeGenCXX/eh.cpp
+++ b/clang/test/CodeGenCXX/eh.cpp
@@ -115,9 +115,12 @@ namespace test7 {
throw 1;
}
-// CHECK: [[CAUGHTEXN:%.*]] = call i8* @llvm.eh.exception()
-// CHECK-NEXT: [[SELECTOR:%.*]] = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*), i8* null)
+// CHECK: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+// CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
+// CHECK-NEXT: catch i8* null
+// CHECK-NEXT: [[CAUGHTEXN:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 0
// CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]]
+// CHECK-NEXT: [[SELECTOR:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 1
// CHECK-NEXT: store i32 [[SELECTOR]], i32* [[SELECTORVAR]]
// CHECK-NEXT: br label
// CHECK: [[SELECTOR:%.*]] = load i32* [[SELECTORVAR]]
@@ -134,9 +137,11 @@ namespace test7 {
throw;
}
}
-// CHECK: [[CAUGHTEXN:%.*]] = call i8* @llvm.eh.exception()
-// CHECK-NEXT: [[SELECTOR:%.*]] = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null)
+// CHECK: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+// CHECK-NEXT: catch i8* null
+// CHECK-NEXT: [[CAUGHTEXN:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 0
// CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]]
+// CHECK-NEXT: [[SELECTOR:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 1
// CHECK-NEXT: store i32 [[SELECTOR]], i32* [[SELECTORVAR]]
// CHECK-NEXT: call void @__cxa_end_catch()
// CHECK-NEXT: br label
@@ -188,8 +193,8 @@ namespace test9 {
// CHECK: invoke void @_ZN5test96opaqueEv()
opaque();
} catch (int x) {
- // CHECK: call i8* @llvm.eh.exception
- // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*))
+ // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
// CHECK: call i8* @__cxa_begin_catch
// CHECK: invoke void @_ZN5test96opaqueEv()
diff --git a/clang/test/CodeGenCXX/nrvo.cpp b/clang/test/CodeGenCXX/nrvo.cpp
index 0efb3553803..57bf27ab7af 100644
--- a/clang/test/CodeGenCXX/nrvo.cpp
+++ b/clang/test/CodeGenCXX/nrvo.cpp
@@ -68,8 +68,10 @@ X test2(bool B) {
// -> %cleanup, %lpad1
// %lpad: landing pad for ctor of 'y', dtor of 'y'
- // CHECK-EH: call i8* @llvm.eh.exception()
- // CHECK-EH: call i32 (i8*, i8*, ...)* @llvm.eh.selector
+ // CHECK-EH: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK-EH-NEXT: cleanup
+ // CHECK-EH-NEXT: extractvalue { i8*, i32 } [[CAUGHTVAL]], 0
+ // CHECK-EH-NEXT: extractvalue { i8*, i32 } [[CAUGHTVAL]], 1
// CHECK-EH-NEXT: br label
// -> %eh.cleanup
@@ -95,12 +97,11 @@ X test2(bool B) {
// %invoke.cont17: rethrow block for %eh.cleanup.
// This really should be elsewhere in the function.
- // CHECK-EH: call void @llvm.eh.resume(
- // CHECK-EH-NEXT: unreachable
+ // CHECK-EH: resume { i8*, i32 }
// %terminate.lpad: terminate landing pad.
- // CHECK-EH: call i8* @llvm.eh.exception()
- // CHECK-EH-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector
+ // CHECK-EH: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK-EH-NEXT: catch i8* null
// CHECK-EH-NEXT: call void @_ZSt9terminatev()
// CHECK-EH-NEXT: unreachable
diff --git a/clang/test/CodeGenCXX/partial-destruction.cpp b/clang/test/CodeGenCXX/partial-destruction.cpp
index b28c1384b8d..f232a159eda 100644
--- a/clang/test/CodeGenCXX/partial-destruction.cpp
+++ b/clang/test/CodeGenCXX/partial-destruction.cpp
@@ -50,7 +50,8 @@ namespace test0 {
// CHECK: ret void
// Partial destroy for initialization.
- // CHECK: llvm.eh.selector({{.*}}, i32 0)
+ // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK-NEXT: cleanup
// CHECK: [[PARTIAL_END:%.*]] = load [[A]]** [[ENDVAR]]
// CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[E_BEGIN]], [[PARTIAL_END]]
// CHECK-NEXT: br i1 [[T0]],
@@ -61,7 +62,8 @@ namespace test0 {
// CHECK-NEXT: br i1 [[T0]],
// Primary EH destructor.
- // CHECK: llvm.eh.selector({{.*}}, i32 0)
+ // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK-NEXT: cleanup
// CHECK: [[E0:%.*]] = getelementptr inbounds [10 x [[A]]]* [[AS]], i32 0, i32 0
// CHECK-NEXT: [[E_END:%.*]] = getelementptr inbounds [[A]]* [[E0]], i64 10
// CHECK-NEXT: br label
@@ -70,7 +72,8 @@ namespace test0 {
// FIXME: There's some really bad block ordering here which causes
// the partial destroy for the primary normal destructor to fall
// within the primary EH destructor.
- // CHECK: llvm.eh.selector({{.*}}, i32 0)
+ // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK-NEXT: cleanup
// CHECK: [[T0:%.*]] = icmp eq [[A]]* [[ED_BEGIN]], [[ED_CUR]]
// CHECK-NEXT: br i1 [[T0]]
// CHECK: [[EDD_AFTER:%.*]] = phi [[A]]* [ [[ED_CUR]], {{%.*}} ], [ [[EDD_CUR:%.*]], {{%.*}} ]
@@ -111,8 +114,10 @@ namespace test1 {
// CHECK-NEXT: ret void
// FIXME: again, the block ordering is pretty bad here
- // CHECK: eh.selector({{.*}}, i32 0)
- // CHECK: eh.selector({{.*}}, i32 0)
+ // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK-NEXT: cleanup
+ // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK-NEXT: cleanup
// CHECK: invoke void @_ZN5test11AD1Ev([[A]]* [[Y]])
// CHECK: invoke void @_ZN5test11AD1Ev([[A]]* [[X]])
}
@@ -139,7 +144,8 @@ namespace test2 {
// CHECK-NEXT: br i1 [[DONE]],
// Partial destruction landing pad.
- // CHECK: llvm.eh.exception()
+ // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK-NEXT: cleanup
// CHECK: [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[CUR]]
// CHECK-NEXT: br i1 [[EMPTY]],
// CHECK: [[PAST:%.*]] = phi [[A]]* [ [[CUR]], {{%.*}} ], [ [[DEL:%.*]], {{%.*}} ]
diff --git a/clang/test/CodeGenCXX/threadsafe-statics-exceptions.cpp b/clang/test/CodeGenCXX/threadsafe-statics-exceptions.cpp
index aa79a4f6dd3..769d120be32 100644
--- a/clang/test/CodeGenCXX/threadsafe-statics-exceptions.cpp
+++ b/clang/test/CodeGenCXX/threadsafe-statics-exceptions.cpp
@@ -21,9 +21,8 @@ void f() {
throw Y();
// Finally, the landing pad.
- // CHECK: call i8* @llvm.eh.exception()
- // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector
+ // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK: cleanup
// CHECK: call void @__cxa_guard_abort(i64* @_ZGVZ1fvE1x)
- // CHECK: call void @llvm.eh.resume(
- // CHECK: unreachable
+ // CHECK: resume { i8*, i32 }
}
diff --git a/clang/test/CodeGenCXX/typeid.cpp b/clang/test/CodeGenCXX/typeid.cpp
index 1af96705ba4..7ebf41c09f6 100644
--- a/clang/test/CodeGenCXX/typeid.cpp
+++ b/clang/test/CodeGenCXX/typeid.cpp
@@ -13,7 +13,8 @@ const char *f() {
// CHECK: invoke void @__cxa_bad_typeid() noreturn
return typeid(*static_cast<A *>(0)).name();
} catch (...) {
- // CHECK: call i8* @llvm.eh.exception
+ // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK-NEXT: catch i8* null
}
return 0;
diff --git a/clang/test/CodeGenObjC/blocks-2.m b/clang/test/CodeGenObjC/blocks-2.m
index 5d63e919fb3..56eb8a7779c 100644
--- a/clang/test/CodeGenObjC/blocks-2.m
+++ b/clang/test/CodeGenObjC/blocks-2.m
@@ -30,8 +30,9 @@ void test1() {
// CHECK-NEXT: call void @_Block_object_dispose(i8* [[T1]], i32 8)
// CHECK-NEXT: ret void
- // CHECK: call i8* @llvm.eh.exception()
+ // CHECK: landingpad { i8*, i32 } personality
+ // CHECK-NEXT: cleanup
// CHECK: [[T1:%.*]] = bitcast [[N_T]]* [[N]] to i8*
// CHECK-NEXT: call void @_Block_object_dispose(i8* [[T1]], i32 8)
- // CHECK: call void @llvm.eh.resume(
+ // CHECK: resume { i8*, i32 }
}
diff --git a/clang/test/CodeGenObjC/gnu-exceptions.m b/clang/test/CodeGenObjC/gnu-exceptions.m
index 7f3ae9df467..8917bf3120d 100644
--- a/clang/test/CodeGenObjC/gnu-exceptions.m
+++ b/clang/test/CodeGenObjC/gnu-exceptions.m
@@ -14,9 +14,9 @@ void test0() {
// CHECK: call void @log(i32 1)
} @catch (C *c) {
- // CHECK: call i8* @llvm.eh.exception()
- // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} @__gnu_objc_personality_v0
- // CHECK: br i1
+ // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gnu_objc_personality_v0 to i8*)
+ // CHECK-NEXT: catch i8* getelementptr inbounds ([2 x i8]* @0, i64 0, i64 0)
+ // CHECK: br i1
// CHECK: call void @log(i32 0)
diff --git a/clang/test/CodeGenObjC/terminate.m b/clang/test/CodeGenObjC/terminate.m
index f04eb6a92bb..0e01d890865 100644
--- a/clang/test/CodeGenObjC/terminate.m
+++ b/clang/test/CodeGenObjC/terminate.m
@@ -14,8 +14,8 @@ void test0(void) {
// CHECK-WITH: call void @destroy(i8** [[PTR]])
// CHECK-WITH-NEXT: ret void
// CHECK-WITH: invoke void @destroy(i8** [[PTR]])
- // CHECK-WITH: call i8* @llvm.eh.exception()
- // CHECK-WITH-NEXT: @llvm.eh.selector
+ // CHECK-WITH: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gcc_personality_v0 to i8*)
+ // CHECK-WITH-NEXT: catch i8* null
// CHECK-WITH-NEXT: call void @objc_terminate()
// CHECK-WITHOUT: define void @test0()
@@ -23,7 +23,7 @@ void test0(void) {
// CHECK-WITHOUT: call void @destroy(i8** [[PTR]])
// CHECK-WITHOUT-NEXT: ret void
// CHECK-WITHOUT: invoke void @destroy(i8** [[PTR]])
- // CHECK-WITHOUT: call i8* @llvm.eh.exception()
- // CHECK-WITHOUT-NEXT: @llvm.eh.selector
+ // CHECK-WITHOUT: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gcc_personality_v0 to i8*)
+ // CHECK-WITHOUT-NEXT: catch i8* null
// CHECK-WITHOUT-NEXT: call void @abort()
}
diff --git a/clang/test/CodeGenObjCXX/catch-id-type.mm b/clang/test/CodeGenObjCXX/catch-id-type.mm
index ece342bb872..b3f99b4fdda 100644
--- a/clang/test/CodeGenObjCXX/catch-id-type.mm
+++ b/clang/test/CodeGenObjCXX/catch-id-type.mm
@@ -30,7 +30,10 @@ id FUNC() {
}
catch( id error )
{
- // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} @__gxx_personality_v0 {{.*}} @_ZTIP4INTF {{.*}} @_ZTIP11objc_object {{.*}} @_ZTIP10objc_class
+ // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ // CHECK-NEXT: catch i8* bitcast ({ i8*, i8*, i32, i8* }* @_ZTIP4INTF to i8*)
+ // CHECK-NEXT: catch i8* bitcast ({ i8*, i8*, i32, i8* }* @_ZTIP11objc_object to i8*)
+ // CHECK-NEXT: catch i8* bitcast ({ i8*, i8*, i32, i8* }* @_ZTIP10objc_class to i8*)
error = error;
groups = [ns_array array];
}
diff --git a/clang/test/CodeGenObjCXX/exceptions.mm b/clang/test/CodeGenObjCXX/exceptions.mm
index d4c0756cb89..9f092b9ac7c 100644
--- a/clang/test/CodeGenObjCXX/exceptions.mm
+++ b/clang/test/CodeGenObjCXX/exceptions.mm
@@ -11,7 +11,8 @@ namespace test0 {
// CHECK: invoke void @_Z6opaquev
opaque();
} catch (OCType *T) {
- // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} @__objc_personality_v0 {{.*}} @"OBJC_EHTYPE_$_OCType"
+ // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*)
+ // CHECK-NEXT: catch %struct._objc_typeinfo* @"OBJC_EHTYPE_$_OCType"
}
}
}
OpenPOWER on IntegriCloud