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.
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.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits