From 15cbbd27e6ee8eefb556604006077938ef9302f9 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Wed, 20 Nov 2013 19:01:50 +0000 Subject: [PATCH] ObjectiveC ARC. Better checking of toll free briding from qualified-id objects to CF types with objc_bridge annotation. // rdar://15454846 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@195264 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ASTContext.cpp | 20 +++++++++----------- test/SemaObjC/objcbridge-attribute.m | 24 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 0d1dc4e4d1..0528a58f89 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -3540,14 +3540,14 @@ bool ASTContext::QIdProtocolsAdoptObjCObjectProtocols(QualType QT, 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 InheritedProtocols; + CollectInheritedProtocols(IDecl, InheritedProtocols); + if (InheritedProtocols.empty()) + return false; + + for (llvm::SmallPtrSet::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::QIdProtocolsAdoptObjCObjectProtocols(QualType QT, break; } if (!Adopts) - return (IDecl->getSuperClass() - ? QIdProtocolsAdoptObjCObjectProtocols(QT, IDecl->getSuperClass()) - : false); + return false; } return true; } diff --git a/test/SemaObjC/objcbridge-attribute.m b/test/SemaObjC/objcbridge-attribute.m index c5bf9f843d..24b7289f8d 100644 --- a/test/SemaObjC/objcbridge-attribute.m +++ b/test/SemaObjC/objcbridge-attribute.m @@ -51,6 +51,7 @@ typedef CFErrorRef1 CFErrorRef2; // expected-note {{declared here}} @protocol P2 @end @protocol P3 @end @protocol P4 @end +@protocol P5 @end @interface NSError @end // expected-note 5 {{declared here}} @@ -103,3 +104,26 @@ void Test6(id P123, id ID, id P1234, id P12, (void)(CFMyErrorRef)P12; // expected-warning {{'id' cannot bridge to 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}} (void)(CFMyErrorRef)P23; // expected-warning {{'id' cannot bridge to 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}} } + +typedef struct __attribute__ ((objc_bridge(MyPersonalError))) __CFMyPersonalErrorRef * CFMyPersonalErrorRef; // expected-note 4 {{declared here}} + +@interface MyPersonalError : NSError // expected-note 4 {{declared here}} +@end + +void Test7(id P123, id ID, id P1234, id P12, id P23) { + (void)(CFMyPersonalErrorRef)ID; // ok + (void)(CFMyPersonalErrorRef)P123; // expected-warning {{'id' cannot bridge to 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}} + (void)(CFMyPersonalErrorRef)P1234; // ok + (void)(CFMyPersonalErrorRef)P12; // expected-warning {{'id' cannot bridge to 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}} + (void)(CFMyPersonalErrorRef)P23; // expected-warning {{'id' cannot bridge to 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}} +} + +void Test8(CFMyPersonalErrorRef cf) { + (void)(id)cf; // ok + (void)(id)cf; // ok + (void)(id)cf; // ok + (void)(id)cf; // ok + (void)(id)cf; // ok + (void)(id)cf; // expected-warning {{'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') bridges to MyPersonalError, not 'id'}} +} + -- 2.40.0