forked from OSchip/llvm-project
ObjectiveC ARC. Better checking of toll free briding
from qualified-id objects to CF types with objc_bridge annotation. // rdar://15454846 llvm-svn: 195264
This commit is contained in:
parent
beee345ab0
commit
91fb0be96a
|
@ -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<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::QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
|
|||
break;
|
||||
}
|
||||
if (!Adopts)
|
||||
return (IDecl->getSuperClass()
|
||||
? QIdProtocolsAdoptObjCObjectProtocols(QT, IDecl->getSuperClass())
|
||||
: false);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -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<P1, P2, P3> @end // expected-note 5 {{declared here}}
|
||||
|
||||
|
@ -103,3 +104,26 @@ void Test6(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12,
|
|||
(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}}
|
||||
|
||||
@interface MyPersonalError : NSError <P4> // expected-note 4 {{declared here}}
|
||||
@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>'}}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue