"@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<
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);
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);
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()) {
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();
/// 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() };
const llvm::StructType *EHTypeTy;
const llvm::Type *EHTypePtrTy;
-
+
ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
~ObjCNonFragileABITypesHelper(){}
};
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);
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();
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;
}
CacheTy = llvm::OpaqueType::get(VMContext);
CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
+
}
ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
// SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
-
+
// struct objc_typeinfo {
// const void** vtable; // objc_ehtype_vtable + 2
}
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()) {
/// 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;
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;
+ }
}
}
}
--- /dev/null
+// 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;
+}