diff options
-rw-r--r-- | clang/lib/CodeGen/CGException.cpp | 113 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 12 | ||||
-rw-r--r-- | clang/test/CXX/except/except.spec/p9-dynamic.cpp | 5 | ||||
-rw-r--r-- | clang/test/CXX/except/except.spec/p9-noexcept.cpp | 3 | ||||
-rw-r--r-- | clang/test/CodeGen/exceptions.c | 6 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/arm.cpp | 10 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/destructors.cpp | 10 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/dynamic-cast.cpp | 3 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/eh.cpp | 17 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/nrvo.cpp | 13 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/partial-destruction.cpp | 18 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/threadsafe-statics-exceptions.cpp | 7 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/typeid.cpp | 3 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/blocks-2.m | 5 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/gnu-exceptions.m | 6 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/terminate.m | 8 | ||||
-rw-r--r-- | clang/test/CodeGenObjCXX/catch-id-type.mm | 5 | ||||
-rw-r--r-- | clang/test/CodeGenObjCXX/exceptions.mm | 3 |
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" } } } |