[PATCH] D31673: Allow casting C pointers declared using extern "C" to ObjC pointer types

Akira Hatanaka via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 4 10:16:47 PDT 2017


ahatanak created this revision.

ARCCastChecker::VisitDeclRefExpr allows casting a constant pointer declared in a header file to an ObjC pointer type. However, it rejects a cast from a variable declared with a language linkage specification (e.g., extern "C") to an ObjC pointer type.

According to the standard, declarations directly contained in a language linkage specification (single line "extern C") are treated as if they contain the extern specifier for the purpose of determining whether they are definitions, so such variables should be treated as declarations unless they have initializers.

This patch replaces the call to VarDecl::getStorageClass (which returns SC_None for extern "C" variables) with a call to VarDecl::isThisDeclarationADefinition to detect variable declarations more precisely.

rdar://problem/29249853


https://reviews.llvm.org/D31673

Files:
  lib/Sema/SemaExprObjC.cpp
  test/SemaObjCXX/arc-bridged-cast.mm


Index: test/SemaObjCXX/arc-bridged-cast.mm
===================================================================
--- test/SemaObjCXX/arc-bridged-cast.mm
+++ test/SemaObjCXX/arc-bridged-cast.mm
@@ -52,3 +52,16 @@
   ref = (__bridge_retained CFAnnotatedObjectRef) CreateSomething();
   ref = (__bridge_retained CFAnnotatedObjectRef) CreateNSString();
 }
+
+extern const CFAnnotatedObjectRef r0;
+extern const CFAnnotatedObjectRef r1 = 0;
+extern "C" const CFAnnotatedObjectRef r2;
+extern "C" const CFAnnotatedObjectRef r3 = 0;
+
+void testExternC() {
+  id obj;
+  obj = (id)r0;
+  obj = (id)r1; // expected-error{{cast of C pointer type 'CFAnnotatedObjectRef' (aka 'const __CFAnnotatedObject *') to Objective-C pointer type 'id' requires a bridged cast}} expected-note{{use __bridge to convert directly}} expected-note{{use __bridge_transfer to transfer ownership of a +1 'CFAnnotatedObjectRef'}}
+  obj = (id)r2;
+  obj = (id)r3; // expected-error{{cast of C pointer type 'CFAnnotatedObjectRef' (aka 'const __CFAnnotatedObject *') to Objective-C pointer type 'id' requires a bridged cast}} expected-note{{use __bridge to convert directly}} expected-note{{use __bridge_transfer to transfer ownership of a +1 'CFAnnotatedObjectRef'}}
+}
Index: lib/Sema/SemaExprObjC.cpp
===================================================================
--- lib/Sema/SemaExprObjC.cpp
+++ lib/Sema/SemaExprObjC.cpp
@@ -3355,7 +3355,7 @@
       if (isAnyRetainable(TargetClass) &&
           isAnyRetainable(SourceClass) &&
           var &&
-          var->getStorageClass() == SC_Extern &&
+          !var->isThisDeclarationADefinition() &&
           var->getType().isConstQualified()) {
 
         // In system headers, they can also be assumed to be immune to retains.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D31673.94087.patch
Type: text/x-patch
Size: 1753 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170404/b789548e/attachment.bin>


More information about the cfe-commits mailing list