summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2014-04-04 23:53:45 +0000
committerFariborz Jahanian <fjahanian@apple.com>2014-04-04 23:53:45 +0000
commit1c3262a3c8beb9779c9195273f674e7b43889b12 (patch)
tree2e226c9b24c8572e1922bfa42b19289b966b4f70
parentf992790cdc215ada87dde7680698a7a25430d1d7 (diff)
downloadclang-1c3262a3c8beb9779c9195273f674e7b43889b12.tar.gz
clang-1c3262a3c8beb9779c9195273f674e7b43889b12.tar.bz2
clang-1c3262a3c8beb9779c9195273f674e7b43889b12.tar.xz
Objective-C arc [Sema]. Allow bridge cast of a qualified-id expression
when bridged Objective-C type conforms to the protocols in CF types's Objective-C class. // rdar://16393330 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@205659 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/ASTContext.cpp20
-rw-r--r--test/SemaObjC/objcbridge-attribute-arc.m26
-rw-r--r--test/SemaObjC/objcbridge-attribute.m26
-rw-r--r--test/SemaObjCXX/objcbridge-attribute-arc.mm26
-rw-r--r--test/SemaObjCXX/objcbridge-attribute.mm26
5 files changed, 70 insertions, 54 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 3ed2a9ff1c..0f3809d538 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -3559,12 +3559,28 @@ bool ASTContext::QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
CollectInheritedProtocols(IDecl, InheritedProtocols);
if (InheritedProtocols.empty())
return false;
-
+ // Check that if every protocol in list of id<plist> conforms to a protcol
+ // of IDecl's, then bridge casting is ok.
+ bool Conforms = false;
+ for (auto *Proto : OPT->quals()) {
+ Conforms = false;
+ for (auto *PI : InheritedProtocols) {
+ if (ProtocolCompatibleWithProtocol(Proto, PI)) {
+ Conforms = true;
+ break;
+ }
+ }
+ if (!Conforms)
+ break;
+ }
+ if (Conforms)
+ return true;
+
for (auto *PI : InheritedProtocols) {
// If both the right and left sides have qualifiers.
bool Adopts = false;
for (auto *Proto : OPT->quals()) {
- // return 'true' if '*PI' is in the inheritance hierarchy of Proto
+ // return 'true' if 'PI' is in the inheritance hierarchy of Proto
if ((Adopts = ProtocolCompatibleWithProtocol(PI, Proto)))
break;
}
diff --git a/test/SemaObjC/objcbridge-attribute-arc.m b/test/SemaObjC/objcbridge-attribute-arc.m
index b2830ff82d..adc6cfcda4 100644
--- a/test/SemaObjC/objcbridge-attribute-arc.m
+++ b/test/SemaObjC/objcbridge-attribute-arc.m
@@ -1,9 +1,9 @@
// RUN: %clang_cc1 -fsyntax-only -x objective-c -fobjc-arc -verify -Wno-objc-root-class %s
// rdar://15454846
-typedef struct __attribute__ ((objc_bridge(NSError))) __CFErrorRef * CFErrorRef; // expected-note 7 {{declared here}}
+typedef struct __attribute__ ((objc_bridge(NSError))) __CFErrorRef * CFErrorRef; // expected-note 5 {{declared here}}
-typedef struct __attribute__ ((objc_bridge(MyError))) __CFMyErrorRef * CFMyErrorRef; // expected-note 3 {{declared here}}
+typedef struct __attribute__ ((objc_bridge(MyError))) __CFMyErrorRef * CFMyErrorRef; // expected-note 1 {{declared here}}
typedef struct __attribute__((objc_bridge(12))) __CFMyColor *CFMyColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}}
@@ -53,9 +53,9 @@ typedef CFErrorRef1 CFErrorRef2; // expected-note 2 {{declared here}}
@protocol P4 @end
@protocol P5 @end
-@interface NSError<P1, P2, P3> @end // expected-note 7 {{declared here}}
+@interface NSError<P1, P2, P3> @end // expected-note 5 {{declared here}}
-@interface MyError : NSError // expected-note 3 {{declared here}}
+@interface MyError : NSError // expected-note 1 {{declared here}}
@end
@interface NSUColor @end
@@ -92,8 +92,8 @@ void Test5(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12,
(void)(CFErrorRef)ID; // ok
(void)(CFErrorRef)P123; // ok
(void)(CFErrorRef)P1234; // ok
- (void)(CFErrorRef)P12; // expected-warning {{'id<P1,P2>' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
- (void)(CFErrorRef)P23; // expected-warning {{'id<P2,P3>' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(CFErrorRef)P12;
+ (void)(CFErrorRef)P23;
}
void Test6(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
@@ -101,21 +101,21 @@ void Test6(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12,
(void)(CFMyErrorRef)ID; // ok
(void)(CFMyErrorRef)P123; // ok
(void)(CFMyErrorRef)P1234; // ok
- (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 *')}}
+ (void)(CFMyErrorRef)P12; // ok
+ (void)(CFMyErrorRef)P23; // ok
}
-typedef struct __attribute__ ((objc_bridge(MyPersonalError))) __CFMyPersonalErrorRef * CFMyPersonalErrorRef; // expected-note 4 {{declared here}}
+typedef struct __attribute__ ((objc_bridge(MyPersonalError))) __CFMyPersonalErrorRef * CFMyPersonalErrorRef; // expected-note 1 {{declared here}}
-@interface MyPersonalError : NSError <P4> // expected-note 4 {{declared here}}
+@interface MyPersonalError : NSError <P4> // expected-note 1 {{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)P123; // ok
(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)(CFMyPersonalErrorRef)P12; // ok
+ (void)(CFMyPersonalErrorRef)P23; // ok
}
void Test8(CFMyPersonalErrorRef cf) {
diff --git a/test/SemaObjC/objcbridge-attribute.m b/test/SemaObjC/objcbridge-attribute.m
index 36b3d604c7..b4d847073d 100644
--- a/test/SemaObjC/objcbridge-attribute.m
+++ b/test/SemaObjC/objcbridge-attribute.m
@@ -1,9 +1,9 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
// rdar://15454846
-typedef struct __attribute__ ((objc_bridge(NSError))) __CFErrorRef * CFErrorRef; // expected-note 5 {{declared here}}
+typedef struct __attribute__ ((objc_bridge(NSError))) __CFErrorRef * CFErrorRef; // expected-note 3 {{declared here}}
-typedef struct __attribute__ ((objc_bridge(MyError))) __CFMyErrorRef * CFMyErrorRef; // expected-note 3 {{declared here}}
+typedef struct __attribute__ ((objc_bridge(MyError))) __CFMyErrorRef * CFMyErrorRef; // expected-note 1 {{declared here}}
typedef struct __attribute__((objc_bridge(12))) __CFMyColor *CFMyColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}}
@@ -53,9 +53,9 @@ typedef CFErrorRef1 CFErrorRef2; // expected-note {{declared here}}
@protocol P4 @end
@protocol P5 @end
-@interface NSError<P1, P2, P3> @end // expected-note 5 {{declared here}}
+@interface NSError<P1, P2, P3> @end // expected-note 3 {{declared here}}
-@interface MyError : NSError // expected-note 3 {{declared here}}
+@interface MyError : NSError // expected-note 1 {{declared here}}
@end
@interface NSUColor @end
@@ -92,8 +92,8 @@ void Test5(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12,
(void)(CFErrorRef)ID; // ok
(void)(CFErrorRef)P123; // ok
(void)(CFErrorRef)P1234; // ok
- (void)(CFErrorRef)P12; // expected-warning {{'id<P1,P2>' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
- (void)(CFErrorRef)P23; // expected-warning {{'id<P2,P3>' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(CFErrorRef)P12; // ok
+ (void)(CFErrorRef)P23; // ok
}
void Test6(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
@@ -101,21 +101,21 @@ void Test6(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12,
(void)(CFMyErrorRef)ID; // ok
(void)(CFMyErrorRef)P123; // ok
(void)(CFMyErrorRef)P1234; // ok
- (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 *')}}
+ (void)(CFMyErrorRef)P12; // ok
+ (void)(CFMyErrorRef)P23; // ok
}
-typedef struct __attribute__ ((objc_bridge(MyPersonalError))) __CFMyPersonalErrorRef * CFMyPersonalErrorRef; // expected-note 4 {{declared here}}
+typedef struct __attribute__ ((objc_bridge(MyPersonalError))) __CFMyPersonalErrorRef * CFMyPersonalErrorRef; // expected-note 1 {{declared here}}
-@interface MyPersonalError : NSError <P4> // expected-note 4 {{declared here}}
+@interface MyPersonalError : NSError <P4> // expected-note 1 {{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)P123; // ok
(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)(CFMyPersonalErrorRef)P12; // ok
+ (void)(CFMyPersonalErrorRef)P23; // ok
}
void Test8(CFMyPersonalErrorRef cf) {
diff --git a/test/SemaObjCXX/objcbridge-attribute-arc.mm b/test/SemaObjCXX/objcbridge-attribute-arc.mm
index 39cba2a842..0e184a4a29 100644
--- a/test/SemaObjCXX/objcbridge-attribute-arc.mm
+++ b/test/SemaObjCXX/objcbridge-attribute-arc.mm
@@ -1,9 +1,9 @@
// RUN: %clang_cc1 -fsyntax-only -x objective-c++ -fobjc-arc -verify -Wno-objc-root-class %s
// rdar://15454846
-typedef struct __attribute__ ((objc_bridge(NSError))) __CFErrorRef * CFErrorRef; // expected-note 7 {{declared here}}
+typedef struct __attribute__ ((objc_bridge(NSError))) __CFErrorRef * CFErrorRef; // expected-note 5 {{declared here}}
-typedef struct __attribute__ ((objc_bridge(MyError))) __CFMyErrorRef * CFMyErrorRef; // expected-note 3 {{declared here}}
+typedef struct __attribute__ ((objc_bridge(MyError))) __CFMyErrorRef * CFMyErrorRef; // expected-note 1 {{declared here}}
typedef struct __attribute__((objc_bridge(12))) __CFMyColor *CFMyColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}}
@@ -53,9 +53,9 @@ typedef CFErrorRef1 CFErrorRef2; // expected-note 2 {{declared here}}
@protocol P4 @end
@protocol P5 @end
-@interface NSError<P1, P2, P3> @end // expected-note 7 {{declared here}}
+@interface NSError<P1, P2, P3> @end // expected-note 5 {{declared here}}
-@interface MyError : NSError // expected-note 3 {{declared here}}
+@interface MyError : NSError // expected-note 1 {{declared here}}
@end
@interface NSUColor @end
@@ -92,8 +92,8 @@ void Test5(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12,
(void)(CFErrorRef)ID; // ok
(void)(CFErrorRef)P123; // ok
(void)(CFErrorRef)P1234; // ok
- (void)(CFErrorRef)P12; // expected-warning {{'id<P1,P2>' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)(CFErrorRef)P23; // expected-warning {{'id<P2,P3>' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}}
+ (void)(CFErrorRef)P12;
+ (void)(CFErrorRef)P23;
}
void Test6(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
@@ -101,21 +101,21 @@ void Test6(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12,
(void)(CFMyErrorRef)ID; // ok
(void)(CFMyErrorRef)P123; // ok
(void)(CFMyErrorRef)P1234; // ok
- (void)(CFMyErrorRef)P12; // expected-warning {{'id<P1,P2>' cannot bridge to 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
- (void)(CFMyErrorRef)P23; // expected-warning {{'id<P2,P3>' cannot bridge to 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P12; // ok
+ (void)(CFMyErrorRef)P23; // ok
}
-typedef struct __attribute__ ((objc_bridge(MyPersonalError))) __CFMyPersonalErrorRef * CFMyPersonalErrorRef; // expected-note 4 {{declared here}}
+typedef struct __attribute__ ((objc_bridge(MyPersonalError))) __CFMyPersonalErrorRef * CFMyPersonalErrorRef; // expected-note 1 {{declared here}}
-@interface MyPersonalError : NSError <P4> // expected-note 4 {{declared here}}
+@interface MyPersonalError : NSError <P4> // expected-note 1 {{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 '__CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P123; // ok
(void)(CFMyPersonalErrorRef)P1234; // ok
- (void)(CFMyPersonalErrorRef)P12; // expected-warning {{'id<P1,P2>' cannot bridge to 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
- (void)(CFMyPersonalErrorRef)P23; // expected-warning {{'id<P2,P3>' cannot bridge to 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P12; // ok
+ (void)(CFMyPersonalErrorRef)P23; // ok
}
void Test8(CFMyPersonalErrorRef cf) {
diff --git a/test/SemaObjCXX/objcbridge-attribute.mm b/test/SemaObjCXX/objcbridge-attribute.mm
index d7a9c65da8..698cf4c957 100644
--- a/test/SemaObjCXX/objcbridge-attribute.mm
+++ b/test/SemaObjCXX/objcbridge-attribute.mm
@@ -1,9 +1,9 @@
// RUN: %clang_cc1 -fsyntax-only -x objective-c++ -verify -Wno-objc-root-class %s
// rdar://15454846
-typedef struct __attribute__ ((objc_bridge(NSError))) __CFErrorRef * CFErrorRef; // expected-note 5 {{declared here}}
+typedef struct __attribute__ ((objc_bridge(NSError))) __CFErrorRef * CFErrorRef; // expected-note 3 {{declared here}}
-typedef struct __attribute__ ((objc_bridge(MyError))) __CFMyErrorRef * CFMyErrorRef; // expected-note 3 {{declared here}}
+typedef struct __attribute__ ((objc_bridge(MyError))) __CFMyErrorRef * CFMyErrorRef; // expected-note 1 {{declared here}}
typedef struct __attribute__((objc_bridge(12))) __CFMyColor *CFMyColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}}
@@ -53,9 +53,9 @@ typedef CFErrorRef1 CFErrorRef2; // expected-note {{declared here}}
@protocol P4 @end
@protocol P5 @end
-@interface NSError<P1, P2, P3> @end // expected-note 5 {{declared here}}
+@interface NSError<P1, P2, P3> @end // expected-note 3 {{declared here}}
-@interface MyError : NSError // expected-note 3 {{declared here}}
+@interface MyError : NSError // expected-note 1 {{declared here}}
@end
@interface NSUColor @end
@@ -92,8 +92,8 @@ void Test5(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12,
(void)(CFErrorRef)ID; // ok
(void)(CFErrorRef)P123; // ok
(void)(CFErrorRef)P1234; // ok
- (void)(CFErrorRef)P12; // expected-warning {{'id<P1,P2>' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)(CFErrorRef)P23; // expected-warning {{'id<P2,P3>' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}}
+ (void)(CFErrorRef)P12; // ok
+ (void)(CFErrorRef)P23; // ok
}
void Test6(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
@@ -101,21 +101,21 @@ void Test6(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12,
(void)(CFMyErrorRef)ID; // ok
(void)(CFMyErrorRef)P123; // ok
(void)(CFMyErrorRef)P1234; // ok
- (void)(CFMyErrorRef)P12; // expected-warning {{'id<P1,P2>' cannot bridge to 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
- (void)(CFMyErrorRef)P23; // expected-warning {{'id<P2,P3>' cannot bridge to 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P12; // ok
+ (void)(CFMyErrorRef)P23; // ok
}
-typedef struct __attribute__ ((objc_bridge(MyPersonalError))) __CFMyPersonalErrorRef * CFMyPersonalErrorRef; // expected-note 4 {{declared here}}
+typedef struct __attribute__ ((objc_bridge(MyPersonalError))) __CFMyPersonalErrorRef * CFMyPersonalErrorRef; // expected-note 1 {{declared here}}
-@interface MyPersonalError : NSError <P4> // expected-note 4 {{declared here}}
+@interface MyPersonalError : NSError <P4> // expected-note 1 {{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 '__CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P123; // ok
(void)(CFMyPersonalErrorRef)P1234; // ok
- (void)(CFMyPersonalErrorRef)P12; // expected-warning {{'id<P1,P2>' cannot bridge to 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
- (void)(CFMyPersonalErrorRef)P23; // expected-warning {{'id<P2,P3>' cannot bridge to 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P12; // ok
+ (void)(CFMyPersonalErrorRef)P23; // ok
}
void Test8(CFMyPersonalErrorRef cf) {