summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CGException.cpp66
-rw-r--r--clang/test/CodeGenObjCXX/exception-cxx.mm13
-rw-r--r--clang/test/CodeGenObjCXX/personality-abuse.mm19
3 files changed, 70 insertions, 28 deletions
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index 255cb841c86..858b83da36e 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -229,6 +229,36 @@ static llvm::Constant *getOpaquePersonalityFn(CodeGenModule &CGM,
return llvm::ConstantExpr::getBitCast(Fn, CGM.Int8PtrTy);
}
+/// Check whether a landingpad instruction only uses C++ features.
+static bool LandingPadHasOnlyCXXUses(llvm::LandingPadInst *LPI) {
+ for (unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {
+ // Look for something that would've been returned by the ObjC
+ // runtime's GetEHType() method.
+ llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();
+ if (LPI->isCatch(I)) {
+ // Check if the catch value has the ObjC prefix.
+ if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
+ // ObjC EH selector entries are always global variables with
+ // names starting like this.
+ if (GV->getName().startswith("OBJC_EHTYPE"))
+ return false;
+ } else {
+ // Check if any of the filter values have the ObjC prefix.
+ llvm::Constant *CVal = cast<llvm::Constant>(Val);
+ for (llvm::User::op_iterator
+ II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {
+ if (llvm::GlobalVariable *GV =
+ cast<llvm::GlobalVariable>((*II)->stripPointerCasts()))
+ // ObjC EH selector entries are always global variables with
+ // names starting like this.
+ if (GV->getName().startswith("OBJC_EHTYPE"))
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
/// Check whether a personality function could reasonably be swapped
/// for a C++ personality function.
static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn) {
@@ -241,34 +271,14 @@ static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn) {
continue;
}
- // Otherwise, it has to be a landingpad instruction.
- llvm::LandingPadInst *LPI = dyn_cast<llvm::LandingPadInst>(U);
- if (!LPI) return false;
-
- for (unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {
- // Look for something that would've been returned by the ObjC
- // runtime's GetEHType() method.
- llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();
- if (LPI->isCatch(I)) {
- // Check if the catch value has the ObjC prefix.
- if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
- // ObjC EH selector entries are always global variables with
- // names starting like this.
- if (GV->getName().startswith("OBJC_EHTYPE"))
- return false;
- } else {
- // Check if any of the filter values have the ObjC prefix.
- llvm::Constant *CVal = cast<llvm::Constant>(Val);
- for (llvm::User::op_iterator
- II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {
- if (llvm::GlobalVariable *GV =
- cast<llvm::GlobalVariable>((*II)->stripPointerCasts()))
- // ObjC EH selector entries are always global variables with
- // names starting like this.
- if (GV->getName().startswith("OBJC_EHTYPE"))
- return false;
- }
- }
+ // Otherwise it must be a function.
+ llvm::Function *F = dyn_cast<llvm::Function>(U);
+ if (!F) return false;
+
+ for (auto BB = F->begin(), E = F->end(); BB != E; ++BB) {
+ if (BB->isLandingPad())
+ if (!LandingPadHasOnlyCXXUses(BB->getLandingPadInst()))
+ return false;
}
}
diff --git a/clang/test/CodeGenObjCXX/exception-cxx.mm b/clang/test/CodeGenObjCXX/exception-cxx.mm
new file mode 100644
index 00000000000..76a5a084582
--- /dev/null
+++ b/clang/test/CodeGenObjCXX/exception-cxx.mm
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -fobjc-exceptions -o - %s | FileCheck %s
+
+// rdar://problem/22155434
+namespace test0 {
+ void foo() {
+ try {
+ throw 0;
+ } catch (...) {
+ return;
+ }
+ }
+// CHECK: define void @_ZN5test03fooEv() #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+}
diff --git a/clang/test/CodeGenObjCXX/personality-abuse.mm b/clang/test/CodeGenObjCXX/personality-abuse.mm
new file mode 100644
index 00000000000..55e0e2c832a
--- /dev/null
+++ b/clang/test/CodeGenObjCXX/personality-abuse.mm
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -fobjc-exceptions -o - %s | FileCheck %s
+
+extern "C" {
+ int __objc_personality_v0();
+}
+
+void *abuse_personality_func() {
+ return (void *)&__objc_personality_v0;
+}
+
+void foo() {
+ try {
+ throw 0;
+ } catch (...) {
+ return;
+ }
+}
+
+// CHECK: define void @_Z3foov() #1 personality i8* bitcast (i32 ()* @__objc_personality_v0 to i8*)
OpenPOWER on IntegriCloud