From c9e266b8cf4abd43167b70609df6039da3ecd9b4 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Thu, 11 Dec 2014 22:56:26 +0000 Subject: [PATCH] [Objective-C]. This patch extends objc_bridge attribute to support objc_bridge(id). This means that a pointer to the struct type to which the attribute appertains is a CF type (and therefore an Objective-C object of some type), but not of any specific class. rdar://19157264 llvm-svn: 224072 --- clang/lib/Lex/PPMacroExpansion.cpp | 1 + clang/lib/Sema/SemaExprObjC.cpp | 3 +++ clang/test/SemaObjC/objcbridge-attribute-arc.m | 16 ++++++++++++++++ 3 files changed, 20 insertions(+) diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index b402a939c57d..d9a7f39913a1 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -912,6 +912,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) { .Case("objc_dictionary_literals", LangOpts.ObjC2) .Case("objc_boxed_expressions", LangOpts.ObjC2) .Case("arc_cf_code_audited", true) + .Case("objc_bridge_id", LangOpts.ObjC2) // C11 features .Case("c_alignas", LangOpts.C11) .Case("c_alignof", LangOpts.C11) diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index eeee352d5e7a..79f7d92e98ce 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -3404,6 +3404,9 @@ static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr, if (TB *ObjCBAttr = getObjCBridgeAttr(TD)) { if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) { HadTheAttribute = true; + if (Parm->isStr("id")) + return true; + NamedDecl *Target = nullptr; // Check for an existing type with this name. LookupResult R(S, DeclarationName(Parm), SourceLocation(), diff --git a/clang/test/SemaObjC/objcbridge-attribute-arc.m b/clang/test/SemaObjC/objcbridge-attribute-arc.m index ee2bf07ed47e..ab8cab8d1919 100644 --- a/clang/test/SemaObjC/objcbridge-attribute-arc.m +++ b/clang/test/SemaObjC/objcbridge-attribute-arc.m @@ -221,3 +221,19 @@ void Test9(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2 (void)(__bridge Class)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'Class'}} (void)(__bridge CFErrorRef)c; // expected-warning {{'__unsafe_unretained Class' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}} } + +// rdar://19157264 +#if __has_feature(objc_bridge_id) +typedef struct __attribute__((objc_bridge(id))) __CFFoo *CFFooRef; +#endif + +id convert(CFFooRef obj) { + (void)(NSError *)obj; // expected-error {{cast of C pointer type 'CFFooRef' (aka 'struct __CFFoo *') to Objective-C pointer type 'NSError *' requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFFooRef' (aka 'struct __CFFoo *') into ARC}} + (void) (__bridge NSError *)obj; + (void) (id)obj; // expected-error {{cast of C pointer type 'CFFooRef' (aka 'struct __CFFoo *') to Objective-C pointer type 'id' requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFFooRef' (aka 'struct __CFFoo *') into ARC}} + return (__bridge id)obj; +}