]> granicus.if.org Git - clang/commitdiff
Alloa catching Objective-C id's being thrown with C++ throw
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 22 Jun 2011 20:21:51 +0000 (20:21 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 22 Jun 2011 20:21:51 +0000 (20:21 +0000)
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

include/clang/Basic/DiagnosticSemaKinds.td
lib/CodeGen/CGException.cpp
lib/CodeGen/CGObjCGNU.cpp
lib/CodeGen/CGObjCMac.cpp
lib/CodeGen/CGObjCRuntime.h
lib/Sema/SemaDeclCXX.cpp
test/CodeGenObjCXX/catch-id-type.mm [new file with mode: 0644]

index 4f3ba0d694b608f8adada7076aeefea239aa76aa..2de09873f6fbb9d59240fc5f656db59e30fc77dd 100644 (file)
@@ -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<
index 1a4a5f988a5818527a4ab45d111f452c72305ca6..79a730eb7ea5f34023961f97b091dd36c960f60b 100644 (file)
@@ -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);
index 6a711bff559563d3a82882b0ca1bf50a5083256a..ed194d9c9180d92b4ff5a7052e83fc9df29fc176 100644 (file)
@@ -438,7 +438,7 @@ public:
                                    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);
@@ -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()) {
index f98770071ecd47d7beaffae0e93b077bc8357f6a..52dd520aa861396185c9df995270744eaa02e2d8 100644 (file)
@@ -200,7 +200,7 @@ public:
   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();
@@ -452,7 +452,7 @@ public:
 
   /// 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() };
@@ -633,7 +633,7 @@ public:
 
   const llvm::StructType *EHTypeTy;
   const llvm::Type *EHTypePtrTy;
-
+  
   ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
   ~ObjCNonFragileABITypesHelper(){}
 };
@@ -1010,7 +1010,7 @@ public:
   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);
 
@@ -1271,7 +1271,7 @@ public:
   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();
@@ -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;
 }
@@ -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)
@@ -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
@@ -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()) {
index 7accc70c9623e6cb45d0c84f3b7e40dccd498390..510143f76781fe03c1cd24e1f7a236cf71fd484c 100644 (file)
@@ -128,7 +128,8 @@ public:
   /// 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;
index 0a7ca4d2f9c26f53cdbc0f448bbfe97976ce93af..93f97f66eec3a4ec84ebfd69fa73a80a077a9280 100644 (file)
@@ -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;
+        }
       }
     }
   }
diff --git a/test/CodeGenObjCXX/catch-id-type.mm b/test/CodeGenObjCXX/catch-id-type.mm
new file mode 100644 (file)
index 0000000..25d3655
--- /dev/null
@@ -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;
+}