Author: vedantk Date: Fri Sep 11 10:40:05 2015 New Revision: 247421 URL: http://llvm.org/viewvc/llvm-project?rev=247421&view=rev Log: [CodeGen] Teach SimplifyPersonality about the updated LandingPadInst
When uses of personality functions were moved from LandingPadInst to Function, we forgot to update SimplifyPersonality(). This patch corrects that. Note: SimplifyPersonality() is an optimization which replaces personality functions with the default C++ personality when possible. Without this update, some ObjC++ projects fail to link against C++ libraries (seeing as the exception ABI had effectively changed). rdar://problem/22155434 Added: cfe/trunk/test/CodeGenObjCXX/exception-cxx.mm cfe/trunk/test/CodeGenObjCXX/personality-abuse.mm Modified: cfe/trunk/lib/CodeGen/CGException.cpp Modified: cfe/trunk/lib/CodeGen/CGException.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=247421&r1=247420&r2=247421&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGException.cpp (original) +++ cfe/trunk/lib/CodeGen/CGException.cpp Fri Sep 11 10:40:05 2015 @@ -229,6 +229,36 @@ static llvm::Constant *getOpaquePersonal 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(ll continue; } - // Otherwise, it has to be a landingpad instruction. - llvm::LandingPadInst *LPI = dyn_cast<llvm::LandingPadInst>(U); - if (!LPI) return false; + // Otherwise it must be a function. + llvm::Function *F = dyn_cast<llvm::Function>(U); + if (!F) 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; - } - } + for (auto BB = F->begin(), E = F->end(); BB != E; ++BB) { + if (BB->isLandingPad()) + if (!LandingPadHasOnlyCXXUses(BB->getLandingPadInst())) + return false; } } Added: cfe/trunk/test/CodeGenObjCXX/exception-cxx.mm URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/exception-cxx.mm?rev=247421&view=auto ============================================================================== --- cfe/trunk/test/CodeGenObjCXX/exception-cxx.mm (added) +++ cfe/trunk/test/CodeGenObjCXX/exception-cxx.mm Fri Sep 11 10:40:05 2015 @@ -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*) +} Added: cfe/trunk/test/CodeGenObjCXX/personality-abuse.mm URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/personality-abuse.mm?rev=247421&view=auto ============================================================================== --- cfe/trunk/test/CodeGenObjCXX/personality-abuse.mm (added) +++ cfe/trunk/test/CodeGenObjCXX/personality-abuse.mm Fri Sep 11 10:40:05 2015 @@ -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*) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits