From e78728a6a6b624ad39a1accf297c773a1e427ba4 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 15 Nov 2013 22:18:17 +0000 Subject: [PATCH] ObjectiveC ARC. Lookup type associated with objc_bridage at the point of CF object type-cast and issue diagnostic if it is not a valid ObjectiveC class. // rdar//15454846. This is wip. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@194861 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 7 ++-- lib/Sema/SemaExprObjC.cpp | 38 ++++++++++++++++++++++ test/SemaObjC/objcbridge-attribute.m | 11 ++++++- 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 23bc87fc99..c34dd21af9 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2435,18 +2435,21 @@ def warn_objc_requires_super_protocol : Warning< def note_protocol_decl : Note< "protocol is declared here">; -// objc_bridge attribute diagnostics. def err_ns_bridged_not_interface : Error< "parameter of 'ns_bridged' attribute does not name an Objective-C class">; + +// objc_bridge attribute diagnostics. def err_objc_bridge_not_id : Error< "parameter of 'objc_bridge' attribute must be a single name of an Objective-C class">; def err_objc_bridge_attribute : Error< "'objc_bridge' attribute must be put on a typedef only">; def err_objc_bridge_not_cftype : Error< "'objc_bridge' attribute must be applied to definition of CF types">; - def err_objc_bridge_not_pointertype : Error< "'objc_bridge' attribute must be applied to a pointer type">; +def err_objc_bridged_not_interface : Error< + "CF object of type %0 with 'objc_bridge' attribute which has parameter that" + " does not name an Objective-C class">; // Function Parameter Semantic Analysis. def err_param_with_void_type : Error<"argument may not have 'void' type">; diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 2db2c77c4b..6ff6bef1ec 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -3165,6 +3165,38 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange, << castRange << castExpr->getSourceRange(); } +static bool CheckObjCBridgeCast(Sema &S, QualType castType, Expr *castExpr) { + QualType T = castExpr->getType(); + while (const TypedefType *TD = dyn_cast(T.getTypePtr())) { + TypedefNameDecl *TDNDecl = TD->getDecl(); + if (TDNDecl->hasAttr()) { + ObjCBridgeAttr *ObjCBAttr = TDNDecl->getAttr(); + IdentifierInfo *Parm = ObjCBAttr->getBridgedType(); + if (Parm && S.getLangOpts().ObjC1) { + // Check for an existing type with this name. + LookupResult R(S, DeclarationName(Parm), SourceLocation(), + Sema::LookupOrdinaryName); + if (S.LookupName(R, S.TUScope)) { + NamedDecl *Target = R.getFoundDecl(); + if (Target && !isa(Target)) { + S.Diag(castExpr->getLocStart(), diag::err_objc_bridged_not_interface) + << castExpr->getType(); + S.Diag(TDNDecl->getLocStart(), diag::note_declared_at); + S.Diag(Target->getLocStart(), diag::note_declared_at); + } + } else { + S.Diag(castExpr->getLocStart(), diag::err_objc_bridged_not_interface) + << castExpr->getType(); + S.Diag(TDNDecl->getLocStart(), diag::note_declared_at); + } + } + return true; + } + T = TDNDecl->getUnderlyingType(); + } + return false; +} + Sema::ARCConversionResult Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType, Expr *&castExpr, CheckedConversionKind CCK, @@ -3222,6 +3254,12 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType, if (castACTC == ACTC_indirectRetainable && exprACTC == ACTC_voidPtr && CCK != CCK_ImplicitConversion) return ACR_okay; + + if (castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation && + (CCK == CCK_CStyleCast || CCK == CCK_FunctionalCast)) + if (CheckObjCBridgeCast(*this, castType, castExpr)) + return ACR_okay; + switch (ARCCastChecker(Context, exprACTC, castACTC, false).Visit(castExpr)) { // For invalid casts, fall through. diff --git a/test/SemaObjC/objcbridge-attribute.m b/test/SemaObjC/objcbridge-attribute.m index 20e348c06c..ddf379a38f 100644 --- a/test/SemaObjC/objcbridge-attribute.m +++ b/test/SemaObjC/objcbridge-attribute.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -verify -Wno-objc-root-class %s // rdar://15454846 typedef struct __CFErrorRef * __attribute__ ((objc_bridge(NSError))) CFErrorRef; @@ -27,3 +27,12 @@ typedef union __CFUColor * __attribute__((objc_bridge(NSUColor))) CFUColorRef; / } @end + +@protocol NSTesting @end +@class NSString; + +typedef struct __CFError * __attribute__((objc_bridge(NSTesting))) CFTestingRef; // expected-note {{declared here}} + +id foo(CFTestingRef cf) { + return (NSString *)cf; // expected-error {{CF object of type 'CFTestingRef' (aka 'struct __CFError *') with 'objc_bridge' attribute which has parameter that does not name an Objective-C class}} +} -- 2.40.0