r194861 - ObjectiveC ARC. Lookup type associated with objc_bridage at

Fariborz Jahanian fjahanian at apple.com
Fri Nov 15 14:18:17 PST 2013


Author: fjahanian
Date: Fri Nov 15 16:18:17 2013
New Revision: 194861

URL: http://llvm.org/viewvc/llvm-project?rev=194861&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/test/SemaObjC/objcbridge-attribute.m

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=194861&r1=194860&r2=194861&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Nov 15 16:18:17 2013
@@ -2435,18 +2435,21 @@ def warn_objc_requires_super_protocol :
 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">;

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=194861&r1=194860&r2=194861&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Fri Nov 15 16:18:17 2013
@@ -3165,6 +3165,38 @@ diagnoseObjCARCConversion(Sema &S, Sourc
     << 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
   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.

Modified: cfe/trunk/test/SemaObjC/objcbridge-attribute.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objcbridge-attribute.m?rev=194861&r1=194860&r2=194861&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/objcbridge-attribute.m (original)
+++ cfe/trunk/test/SemaObjC/objcbridge-attribute.m Fri Nov 15 16:18:17 2013
@@ -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__
 
 }
 @end
+
+ at protocol NSTesting @end
+ at 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}}
+}





More information about the cfe-commits mailing list