Objective-C ARC. Allow conversion of (void*) pointers to

retainable ObjC pointers without requiring a bridge-cast
in the context of pointer comparison as this is in effect 
a +0 context. // rdar://16627903

llvm-svn: 211243
This commit is contained in:
Fariborz Jahanian 2014-06-18 23:52:49 +00:00
parent 2dfa00f6f2
commit c03ef578eb
4 changed files with 28 additions and 6 deletions

View File

@ -7820,7 +7820,9 @@ public:
ARCConversionResult CheckObjCARCConversion(SourceRange castRange, ARCConversionResult CheckObjCARCConversion(SourceRange castRange,
QualType castType, Expr *&op, QualType castType, Expr *&op,
CheckedConversionKind CCK, CheckedConversionKind CCK,
bool DiagnoseCFAudited = false); bool DiagnoseCFAudited = false,
BinaryOperatorKind Opc = BO_PtrMemD
);
Expr *stripARCUnbridgedCast(Expr *e); Expr *stripARCUnbridgedCast(Expr *e);
void diagnoseARCUnbridgedCast(Expr *e); void diagnoseARCUnbridgedCast(Expr *e);

View File

@ -8149,7 +8149,8 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
else { else {
Expr *E = RHS.get(); Expr *E = RHS.get();
if (getLangOpts().ObjCAutoRefCount) if (getLangOpts().ObjCAutoRefCount)
CheckObjCARCConversion(SourceRange(), LHSType, E, CCK_ImplicitConversion); CheckObjCARCConversion(SourceRange(), LHSType, E, CCK_ImplicitConversion, false,
Opc);
RHS = ImpCastExprToType(E, LHSType, RHS = ImpCastExprToType(E, LHSType,
LPT ? CK_BitCast :CK_CPointerToObjCPointerCast); LPT ? CK_BitCast :CK_CPointerToObjCPointerCast);
} }

View File

@ -3624,7 +3624,8 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
Sema::ARCConversionResult Sema::ARCConversionResult
Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType, Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
Expr *&castExpr, CheckedConversionKind CCK, Expr *&castExpr, CheckedConversionKind CCK,
bool DiagnoseCFAudited) { bool DiagnoseCFAudited,
BinaryOperatorKind Opc) {
QualType castExprType = castExpr->getType(); QualType castExprType = castExpr->getType();
// For the purposes of the classification, we assume reference types // For the purposes of the classification, we assume reference types
@ -3718,8 +3719,10 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
// instead. // instead.
if (!DiagnoseCFAudited || exprACTC != ACTC_retainable || if (!DiagnoseCFAudited || exprACTC != ACTC_retainable ||
castACTC != ACTC_coreFoundation) castACTC != ACTC_coreFoundation)
diagnoseObjCARCConversion(*this, castRange, castType, castACTC, if (!(exprACTC == ACTC_voidPtr && castACTC == ACTC_retainable &&
castExpr, castExpr, exprACTC, CCK); (Opc == BO_NE || Opc == BO_EQ)))
diagnoseObjCARCConversion(*this, castRange, castType, castACTC,
castExpr, castExpr, exprACTC, CCK);
return ACR_okay; return ACR_okay;
} }

View File

@ -285,7 +285,7 @@ void test11(id op, void *vp) {
b = (nil == vp); b = (nil == vp);
b = (vp == op); // expected-error {{implicit conversion of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast}} expected-note {{use __bridge}} expected-note {{use CFBridgingRetain call}} b = (vp == op); // expected-error {{implicit conversion of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast}} expected-note {{use __bridge}} expected-note {{use CFBridgingRetain call}}
b = (op == vp); // expected-error {{implicit conversion of C pointer type 'void *' to Objective-C pointer type 'id' requires a bridged cast}} expected-note {{use __bridge}} expected-note {{use CFBridgingRelease call}} b = (op == vp);
} }
void test12(id collection) { void test12(id collection) {
@ -782,3 +782,19 @@ void foo(NSArray *array) {
} }
} }
} }
// rdar://16627903
extern void abort();
#define TKAssertEqual(a, b) do{\
__typeof(a) a_res = (a);\
__typeof(b) b_res = (b);\
if ((a_res) != (b_res)) {\
abort();\
}\
}while(0)
int garf() {
id object;
TKAssertEqual(object, nil);
TKAssertEqual(object, (id)nil);
}