Skip to content

Commit

Permalink
Alloa catching Objective-C id's being thrown with C++ throw
Browse files Browse the repository at this point in the history
in Darwin's fragile abi mode.  // rdar://8940528


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133639 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Fariborz Jahanian committed Jun 22, 2011
1 parent 0d9106f commit 9d96bce
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 16 deletions.
7 changes: 5 additions & 2 deletions include/clang/Basic/DiagnosticSemaKinds.td
Expand Up @@ -3151,9 +3151,12 @@ def err_qualified_objc_catch_parm : Error<
"@catch parameter declarator cannot be qualified">;
def err_objc_pointer_cxx_catch_gnu : Error<
"can't catch Objective C exceptions in C++ in the GNU runtime">;
def err_objc_pointer_cxx_catch_fragile : Error<
"can't catch Objective C exceptions in C++ in the non-unified "
def warn_objc_pointer_cxx_catch_fragile : Warning<
"catching Objective C id's exceptions in C++ in the non-unified "
"exception model">;
def err_objc_pointer_cxx_catch_fragile : Error<
"can't catch Objective C exceptions in C++ in the non-unified "
"exception model">;
def err_objc_object_catch : Error<
"can't catch an Objective C object by value">;
def err_incomplete_type_objc_at_encode : Error<
Expand Down
2 changes: 1 addition & 1 deletion lib/CodeGen/CGException.cpp
Expand Up @@ -521,7 +521,7 @@ void CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {

llvm::Value *TypeInfo = 0;
if (CaughtType->isObjCObjectPointerType())
TypeInfo = CGM.getObjCRuntime().GetEHType(CaughtType);
TypeInfo = CGM.getObjCRuntime().GetEHType(CaughtType, this);
else
TypeInfo = CGM.GetAddrOfRTTIDescriptor(CaughtType, /*ForEH=*/true);
CatchScope->setHandler(I, TypeInfo, Handler);
Expand Down
4 changes: 2 additions & 2 deletions lib/CodeGen/CGObjCGNU.cpp
Expand Up @@ -438,7 +438,7 @@ class CGObjCGNU : public CGObjCRuntime {
bool lval = false);
virtual llvm::Value *GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
*Method);
virtual llvm::Constant *GetEHType(QualType T);
virtual llvm::Constant *GetEHType(QualType T, const CodeGenFunction *CGF=0);

virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
const ObjCContainerDecl *CD);
Expand Down Expand Up @@ -832,7 +832,7 @@ llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
return GetSelector(Builder, Method->getSelector(), SelTypes, false);
}

llvm::Constant *CGObjCGNU::GetEHType(QualType T) {
llvm::Constant *CGObjCGNU::GetEHType(QualType T, const CodeGenFunction *CGF) {
if (!CGM.getLangOptions().CPlusPlus) {
if (T->isObjCIdType()
|| T->isObjCQualifiedIdType()) {
Expand Down
22 changes: 14 additions & 8 deletions lib/CodeGen/CGObjCMac.cpp
Expand Up @@ -200,7 +200,7 @@ class ObjCCommonTypesHelper {
const llvm::Type *CacheTy;
/// CachePtrTy - LLVM type for struct objc_cache *.
const llvm::Type *CachePtrTy;

llvm::Constant *getGetPropertyFn() {
CodeGen::CodeGenTypes &Types = CGM.getTypes();
ASTContext &Ctx = CGM.getContext();
Expand Down Expand Up @@ -452,7 +452,7 @@ class ObjCTypesHelper : public ObjCCommonTypesHelper {

/// ExceptionDataTy - LLVM type for struct _objc_exception_data.
const llvm::Type *ExceptionDataTy;

/// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
llvm::Constant *getExceptionTryEnterFn() {
const llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
Expand Down Expand Up @@ -633,7 +633,7 @@ class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {

const llvm::StructType *EHTypeTy;
const llvm::Type *EHTypePtrTy;

ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
~ObjCNonFragileABITypesHelper(){}
};
Expand Down Expand Up @@ -1010,7 +1010,7 @@ class CGObjCMac : public CGObjCCommonMac {
virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
const ObjCMethodDecl *Method);

virtual llvm::Constant *GetEHType(QualType T);
virtual llvm::Constant *GetEHType(QualType T, const CodeGenFunction *CGF=0);

virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);

Expand Down Expand Up @@ -1271,7 +1271,7 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
const ObjCProtocolDecl *PD);

virtual llvm::Constant *GetEHType(QualType T);
virtual llvm::Constant *GetEHType(QualType T, const CodeGenFunction *CGF=0);

virtual llvm::Constant *GetPropertyGetFunction() {
return ObjCTypes.getGetPropertyFn();
Expand Down Expand Up @@ -1414,7 +1414,12 @@ llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
return EmitSelector(Builder, Method->getSelector());
}

llvm::Constant *CGObjCMac::GetEHType(QualType T) {
llvm::Constant *CGObjCMac::GetEHType(QualType T, const CodeGenFunction *CGF) {
if (T->isObjCIdType() ||
T->isObjCQualifiedIdType()) {
return CGM.GetAddrOfRTTIDescriptor(
CGF->getContext().ObjCIdRedefinitionType, /*ForEH=*/true);
}
llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
return 0;
}
Expand Down Expand Up @@ -4176,6 +4181,7 @@ ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
CacheTy = llvm::OpaqueType::get(VMContext);
CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
CachePtrTy = llvm::PointerType::getUnqual(CacheTy);

}

ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
Expand Down Expand Up @@ -4580,7 +4586,7 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul

// SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);


// struct objc_typeinfo {
// const void** vtable; // objc_ehtype_vtable + 2
Expand Down Expand Up @@ -6015,7 +6021,7 @@ CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
}

llvm::Constant *
CGObjCNonFragileABIMac::GetEHType(QualType T) {
CGObjCNonFragileABIMac::GetEHType(QualType T, const CodeGenFunction *CGF) {
// There's a particular fixed type info for 'id'.
if (T->isObjCIdType() ||
T->isObjCQualifiedIdType()) {
Expand Down
3 changes: 2 additions & 1 deletion lib/CodeGen/CGObjCRuntime.h
Expand Up @@ -128,7 +128,8 @@ class CGObjCRuntime {
/// This is used externally to implement catching ObjC types in C++.
/// Runtimes which don't support this should add the appropriate
/// error to Sema.
virtual llvm::Constant *GetEHType(QualType T) = 0;
virtual llvm::Constant *GetEHType(QualType T,
const CodeGenFunction *CGF=0) = 0;

/// Generate a constant string object.
virtual llvm::Constant *GenerateConstantString(const StringLiteral *) = 0;
Expand Down
8 changes: 6 additions & 2 deletions lib/Sema/SemaDeclCXX.cpp
Expand Up @@ -8046,8 +8046,12 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S,
Invalid = true;
} else if (T->isObjCObjectPointerType()) {
if (!getLangOptions().ObjCNonFragileABI) {
Diag(Loc, diag::err_objc_pointer_cxx_catch_fragile);
Invalid = true;
if (T->isObjCIdType() || T->isObjCQualifiedIdType())
Diag(Loc, diag::warn_objc_pointer_cxx_catch_fragile);
else {
Diag(Loc, diag::err_objc_pointer_cxx_catch_fragile);
Invalid = true;
}
}
}
}
Expand Down
33 changes: 33 additions & 0 deletions test/CodeGenObjCXX/catch-id-type.mm
@@ -0,0 +1,33 @@
// RUN: %clang_cc1 -triple i386-apple-macosx10.6.6 -emit-llvm -fobjc-exceptions -fcxx-exceptions -fexceptions -o - %s | FileCheck %s
// rdar://8940528

@interface ns_array
+ (id) array;
@end

@implementation ns_array
+ (id) array { return 0; }
@end

id Groups();

id FUNC() {
id groups;
try
{
groups = Groups(); // throws on errors.
}
catch( id error )
{
// CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} @__gxx_personality_v0 {{.*}} @_ZTIP11objc_object
error = error;
groups = [ns_array array];
}
return groups;

}

int main() {
FUNC();
return 0;
}

0 comments on commit 9d96bce

Please sign in to comment.