From: Fariborz Jahanian Date: Fri, 4 Apr 2014 23:53:45 +0000 (+0000) Subject: Objective-C arc [Sema]. Allow bridge cast of a qualified-id expression X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1c3262a3c8beb9779c9195273f674e7b43889b12;p=clang 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 --- 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 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 @end // expected-note 7 {{declared here}} +@interface NSError @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 P123, id ID, id P1234, id P12, (void)(CFErrorRef)ID; // ok (void)(CFErrorRef)P123; // ok (void)(CFErrorRef)P1234; // ok - (void)(CFErrorRef)P12; // expected-warning {{'id' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}} - (void)(CFErrorRef)P23; // expected-warning {{'id' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}} + (void)(CFErrorRef)P12; + (void)(CFErrorRef)P23; } void Test6(id P123, id ID, id P1234, id P12, id P23) { @@ -101,21 +101,21 @@ void Test6(id P123, id ID, id P1234, id P12, (void)(CFMyErrorRef)ID; // ok (void)(CFMyErrorRef)P123; // ok (void)(CFMyErrorRef)P1234; // ok - (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 *')}} + (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 // expected-note 4 {{declared here}} +@interface MyPersonalError : NSError // expected-note 1 {{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)P123; // ok (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)(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 @end // expected-note 5 {{declared here}} +@interface NSError @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 P123, id ID, id P1234, id P12, (void)(CFErrorRef)ID; // ok (void)(CFErrorRef)P123; // ok (void)(CFErrorRef)P1234; // ok - (void)(CFErrorRef)P12; // expected-warning {{'id' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}} - (void)(CFErrorRef)P23; // expected-warning {{'id' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}} + (void)(CFErrorRef)P12; // ok + (void)(CFErrorRef)P23; // ok } void Test6(id P123, id ID, id P1234, id P12, id P23) { @@ -101,21 +101,21 @@ void Test6(id P123, id ID, id P1234, id P12, (void)(CFMyErrorRef)ID; // ok (void)(CFMyErrorRef)P123; // ok (void)(CFMyErrorRef)P1234; // ok - (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 *')}} + (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 // expected-note 4 {{declared here}} +@interface MyPersonalError : NSError // expected-note 1 {{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)P123; // ok (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)(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 @end // expected-note 7 {{declared here}} +@interface NSError @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 P123, id ID, id P1234, id P12, (void)(CFErrorRef)ID; // ok (void)(CFErrorRef)P123; // ok (void)(CFErrorRef)P1234; // ok - (void)(CFErrorRef)P12; // expected-warning {{'id' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}} - (void)(CFErrorRef)P23; // expected-warning {{'id' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}} + (void)(CFErrorRef)P12; + (void)(CFErrorRef)P23; } void Test6(id P123, id ID, id P1234, id P12, id P23) { @@ -101,21 +101,21 @@ void Test6(id P123, id ID, id P1234, id P12, (void)(CFMyErrorRef)ID; // ok (void)(CFMyErrorRef)P123; // ok (void)(CFMyErrorRef)P1234; // ok - (void)(CFMyErrorRef)P12; // expected-warning {{'id' cannot bridge to 'CFMyErrorRef' (aka '__CFMyErrorRef *')}} - (void)(CFMyErrorRef)P23; // expected-warning {{'id' 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 // expected-note 4 {{declared here}} +@interface MyPersonalError : NSError // expected-note 1 {{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 '__CFMyPersonalErrorRef *')}} + (void)(CFMyPersonalErrorRef)P123; // ok (void)(CFMyPersonalErrorRef)P1234; // ok - (void)(CFMyPersonalErrorRef)P12; // expected-warning {{'id' cannot bridge to 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}} - (void)(CFMyPersonalErrorRef)P23; // expected-warning {{'id' 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 @end // expected-note 5 {{declared here}} +@interface NSError @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 P123, id ID, id P1234, id P12, (void)(CFErrorRef)ID; // ok (void)(CFErrorRef)P123; // ok (void)(CFErrorRef)P1234; // ok - (void)(CFErrorRef)P12; // expected-warning {{'id' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}} - (void)(CFErrorRef)P23; // expected-warning {{'id' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}} + (void)(CFErrorRef)P12; // ok + (void)(CFErrorRef)P23; // ok } void Test6(id P123, id ID, id P1234, id P12, id P23) { @@ -101,21 +101,21 @@ void Test6(id P123, id ID, id P1234, id P12, (void)(CFMyErrorRef)ID; // ok (void)(CFMyErrorRef)P123; // ok (void)(CFMyErrorRef)P1234; // ok - (void)(CFMyErrorRef)P12; // expected-warning {{'id' cannot bridge to 'CFMyErrorRef' (aka '__CFMyErrorRef *')}} - (void)(CFMyErrorRef)P23; // expected-warning {{'id' 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 // expected-note 4 {{declared here}} +@interface MyPersonalError : NSError // expected-note 1 {{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 '__CFMyPersonalErrorRef *')}} + (void)(CFMyPersonalErrorRef)P123; // ok (void)(CFMyPersonalErrorRef)P1234; // ok - (void)(CFMyPersonalErrorRef)P12; // expected-warning {{'id' cannot bridge to 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}} - (void)(CFMyPersonalErrorRef)P23; // expected-warning {{'id' cannot bridge to 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}} + (void)(CFMyPersonalErrorRef)P12; // ok + (void)(CFMyPersonalErrorRef)P23; // ok } void Test8(CFMyPersonalErrorRef cf) {