summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td7
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp38
-rw-r--r--clang/test/SemaObjC/objcbridge-attribute.m11
3 files changed, 53 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 23bc87fc993..c34dd21af95 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/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/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
index 2db2c77c4bc..6ff6bef1ec7 100644
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ b/clang/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<TypedefType>(T.getTypePtr())) {
+ TypedefNameDecl *TDNDecl = TD->getDecl();
+ if (TDNDecl->hasAttr<ObjCBridgeAttr>()) {
+ ObjCBridgeAttr *ObjCBAttr = TDNDecl->getAttr<ObjCBridgeAttr>();
+ 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<ObjCInterfaceDecl>(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/clang/test/SemaObjC/objcbridge-attribute.m b/clang/test/SemaObjC/objcbridge-attribute.m
index 20e348c06ce..ddf379a38f7 100644
--- a/clang/test/SemaObjC/objcbridge-attribute.m
+++ b/clang/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}}
+}
OpenPOWER on IntegriCloud