]> granicus.if.org Git - clang/commitdiff
Support for catching objc pointer objects in c++ catch-statement
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 23 Jun 2011 19:00:08 +0000 (19:00 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 23 Jun 2011 19:00:08 +0000 (19:00 +0000)
in fragile abi mode and some other cleanups. // rdar://8940528

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133747 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticGroups.td
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
test/SemaObjCXX/exceptions-fragile.mm

index 7881ad3ad66f2b176dc35b334eec366212ce1ac0..8a109149884f119a016a96b348a94c9485313bfa 100644 (file)
@@ -296,3 +296,6 @@ def GNU : DiagGroup<"gnu", [GNUDesignator, VLA]>;
 
 // A warning group for warnings about Microsoft extensions.
 def Microsoft : DiagGroup<"microsoft">;
+
+def ObjCNonUnifiedException : DiagGroup<"objc-nonunified-exceptions">;
+
index 6b710f5f1efca70d89a1f1081e75a93ab508a9cd..fb031596d5b8ed545c2bb154213619eabb97f714 100644 (file)
@@ -3154,11 +3154,8 @@ def err_qualified_objc_catch_parm : Error<
 def err_objc_pointer_cxx_catch_gnu : Error<
   "can't catch Objective C exceptions in C++ in the GNU runtime">;
 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">;
+  "catching Objective C exceptions in C++ in the non-unified "
+  "exception model">, InGroup<ObjCNonUnifiedException>;
 def err_objc_object_catch : Error<
   "can't catch an Objective C object by value">;
 def err_incomplete_type_objc_at_encode : Error<
index 79a730eb7ea5f34023961f97b091dd36c960f60b..1a4a5f988a5818527a4ab45d111f452c72305ca6 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, this);
+        TypeInfo = CGM.getObjCRuntime().GetEHType(CaughtType);
       else
         TypeInfo = CGM.GetAddrOfRTTIDescriptor(CaughtType, /*ForEH=*/true);
       CatchScope->setHandler(I, TypeInfo, Handler);
index ed194d9c9180d92b4ff5a7052e83fc9df29fc176..6a711bff559563d3a82882b0ca1bf50a5083256a 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, const CodeGenFunction *CGF=0);
+  virtual llvm::Constant *GetEHType(QualType T);
 
   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, const CodeGenFunction *CGF) {
+llvm::Constant *CGObjCGNU::GetEHType(QualType T) {
   if (!CGM.getLangOptions().CPlusPlus) {
       if (T->isObjCIdType()
           || T->isObjCQualifiedIdType()) {
index 52dd520aa861396185c9df995270744eaa02e2d8..d518372f9c99f40c15adac3a83e65ec8dd800b32 100644 (file)
@@ -1010,7 +1010,7 @@ public:
   virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
                                    const ObjCMethodDecl *Method);
 
-  virtual llvm::Constant *GetEHType(QualType T, const CodeGenFunction *CGF=0);
+  virtual llvm::Constant *GetEHType(QualType T);
 
   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, const CodeGenFunction *CGF=0);
+  virtual llvm::Constant *GetEHType(QualType T);
 
   virtual llvm::Constant *GetPropertyGetFunction() {
     return ObjCTypes.getGetPropertyFn();
@@ -1414,12 +1414,20 @@ llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
   return EmitSelector(Builder, Method->getSelector());
 }
 
-llvm::Constant *CGObjCMac::GetEHType(QualType T, const CodeGenFunction *CGF) {
+llvm::Constant *CGObjCMac::GetEHType(QualType T) {
   if (T->isObjCIdType() ||
       T->isObjCQualifiedIdType()) {
     return CGM.GetAddrOfRTTIDescriptor(
-              CGF->getContext().ObjCIdRedefinitionType, /*ForEH=*/true);
+              CGM.getContext().ObjCIdRedefinitionType, /*ForEH=*/true);
   }
+  if (T->isObjCClassType() ||
+      T->isObjCQualifiedClassType()) {
+    return CGM.GetAddrOfRTTIDescriptor(
+             CGM.getContext().ObjCClassRedefinitionType, /*ForEH=*/true);
+  }
+  if (T->isObjCObjectPointerType())
+    return CGM.GetAddrOfRTTIDescriptor(T,  /*ForEH=*/true);
+  
   llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
   return 0;
 }
@@ -6021,7 +6029,7 @@ CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
 }
 
 llvm::Constant *
-CGObjCNonFragileABIMac::GetEHType(QualType T, const CodeGenFunction *CGF) {
+CGObjCNonFragileABIMac::GetEHType(QualType T) {
   // There's a particular fixed type info for 'id'.
   if (T->isObjCIdType() ||
       T->isObjCQualifiedIdType()) {
index 510143f76781fe03c1cd24e1f7a236cf71fd484c..7accc70c9623e6cb45d0c84f3b7e40dccd498390 100644 (file)
@@ -128,8 +128,7 @@ 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, 
-                                    const CodeGenFunction *CGF=0) = 0;
+  virtual llvm::Constant *GetEHType(QualType T) = 0;
 
   /// Generate a constant string object.
   virtual llvm::Constant *GenerateConstantString(const StringLiteral *) = 0;
index 93f97f66eec3a4ec84ebfd69fa73a80a077a9280..a7bd46a2ca751747b93fc742cf57163871f56381 100644 (file)
@@ -8045,14 +8045,8 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S,
       Diag(Loc, diag::err_objc_object_catch);
       Invalid = true;
     } else if (T->isObjCObjectPointerType()) {
-      if (!getLangOptions().ObjCNonFragileABI) {
-        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;
-        }
-      }
+      if (!getLangOptions().ObjCNonFragileABI)
+        Diag(Loc, diag::warn_objc_pointer_cxx_catch_fragile);
     }
   }
 
index 25d36550e8e2d5a363e5bf85d543da29fe82c9dc..ece342bb87205f4335278e89abe19687f66864cd 100644 (file)
 
 id Groups();
 
+@protocol P @end;
+
+@interface INTF<P> {
+    double dd;
+}
+@end
+
 id FUNC() {
     id groups;
     try
     {
       groups = Groups();  // throws on errors.
     }
+    catch( INTF<P>* error )
+    {
+      Groups();
+    }
     catch( id error )
     { 
-      // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} @__gxx_personality_v0 {{.*}} @_ZTIP11objc_object
+      // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} @__gxx_personality_v0 {{.*}} @_ZTIP4INTF {{.*}} @_ZTIP11objc_object {{.*}} @_ZTIP10objc_class
       error = error; 
       groups = [ns_array array]; 
     }
+    catch (Class cl) {
+      cl = cl;
+      groups = [ns_array array];
+    }
     return groups;
 
 }
index d1e7077089e2cebd531b1ece62ac311fa7f38d14..ebbf6a0374d355db4471b66d6980f18f3e3c9a60 100644 (file)
@@ -6,7 +6,7 @@ void opaque();
 namespace test0 {
   void test() {
     try {
-    } catch (NSException *e) { // expected-error {{can't catch Objective C exceptions in C++ in the non-unified exception model}}
+    } catch (NSException *e) { // expected-warning {{catching Objective C exceptions in C++ in the non-unified exception model [-Wobjc-nonunified-exceptions]}}
     }
   }
 }