r195264 - ObjectiveC ARC. Better checking of toll free briding

Fariborz Jahanian fjahanian at apple.com
Wed Nov 20 11:01:50 PST 2013


Author: fjahanian
Date: Wed Nov 20 13:01:50 2013
New Revision: 195264

URL: http://llvm.org/viewvc/llvm-project?rev=195264&view=rev
Log:
ObjectiveC ARC. Better checking of toll free briding 
from qualified-id objects to CF types with 
objc_bridge annotation. // rdar://15454846

Modified:
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/test/SemaObjC/objcbridge-attribute.m

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=195264&r1=195263&r2=195264&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Nov 20 13:01:50 2013
@@ -3540,14 +3540,14 @@ bool ASTContext::QIdProtocolsAdoptObjCOb
     return false;
   if (!IDecl->hasDefinition())
     return false;
-  ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
-                                       E = IDecl->protocol_end();
-  if (PI == E)
-    return (IDecl->getSuperClass()
-             ? QIdProtocolsAdoptObjCObjectProtocols(QT, IDecl->getSuperClass())
-             : false);
-  
-  for (; PI != E; ++PI) {
+  llvm::SmallPtrSet<ObjCProtocolDecl *, 8> InheritedProtocols;
+  CollectInheritedProtocols(IDecl, InheritedProtocols);
+  if (InheritedProtocols.empty())
+    return false;
+      
+  for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator PI =
+       InheritedProtocols.begin(),
+       E = InheritedProtocols.end(); PI != E; ++PI) {
     // If both the right and left sides have qualifiers.
     bool Adopts = false;
     for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
@@ -3558,9 +3558,7 @@ bool ASTContext::QIdProtocolsAdoptObjCOb
         break;
     }
     if (!Adopts)
-      return (IDecl->getSuperClass()
-              ? QIdProtocolsAdoptObjCObjectProtocols(QT, IDecl->getSuperClass())
-              : false);
+      return false;
   }
   return true;
 }

Modified: cfe/trunk/test/SemaObjC/objcbridge-attribute.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objcbridge-attribute.m?rev=195264&r1=195263&r2=195264&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/objcbridge-attribute.m (original)
+++ cfe/trunk/test/SemaObjC/objcbridge-attribute.m Wed Nov 20 13:01:50 2013
@@ -51,6 +51,7 @@ typedef CFErrorRef1 CFErrorRef2; // expe
 @protocol P2 @end
 @protocol P3 @end
 @protocol P4 @end
+ at protocol P5 @end
 
 @interface NSError<P1, P2, P3> @end // expected-note 5 {{declared here}}
 
@@ -103,3 +104,26 @@ void Test6(id<P1, P2, P3> P123, id ID, i
  (void)(CFMyErrorRef)P12; // expected-warning {{'id<P1,P2>' cannot bridge to 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}}
  (void)(CFMyErrorRef)P23; // expected-warning {{'id<P2,P3>' cannot bridge to 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}}
 }
+
+typedef struct __attribute__ ((objc_bridge(MyPersonalError))) __CFMyPersonalErrorRef * CFMyPersonalErrorRef;  // expected-note 4 {{declared here}}
+
+ at interface MyPersonalError : NSError <P4> // expected-note 4 {{declared here}}
+ at end
+
+void Test7(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
+ (void)(CFMyPersonalErrorRef)ID; // ok
+ (void)(CFMyPersonalErrorRef)P123; // expected-warning {{'id<P1,P2,P3>' cannot bridge to 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P1234; // ok
+ (void)(CFMyPersonalErrorRef)P12; //  expected-warning {{'id<P1,P2>' cannot bridge to 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P23; //  expected-warning {{'id<P2,P3>' cannot bridge to 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}}
+}
+
+void Test8(CFMyPersonalErrorRef cf) {
+  (void)(id)cf; // ok
+  (void)(id<P1>)cf; // ok
+  (void)(id<P1, P2>)cf; // ok
+  (void)(id<P1, P2, P3>)cf; // ok
+  (void)(id<P1, P2, P3, P4>)cf; // ok
+  (void)(id<P1, P2, P3, P4, P5>)cf; // expected-warning {{'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') bridges to MyPersonalError, not 'id<P1,P2,P3,P4,P5>'}}
+}
+





More information about the cfe-commits mailing list