forked from OSchip/llvm-project
objective-c arc: When function calls with known CFCreate naming convention
are cast to retainable types, only suggest CFBridgingRelease/ CFBridgingRetain and not the __bridge casts. // rdar://11923822 llvm-svn: 160900
This commit is contained in:
parent
86ca9f9e11
commit
36986c6e0f
|
@ -2541,6 +2541,7 @@ namespace {
|
|||
ASTContext &Context;
|
||||
ARCConversionTypeClass SourceClass;
|
||||
ARCConversionTypeClass TargetClass;
|
||||
bool Diagnose;
|
||||
|
||||
static bool isCFType(QualType type) {
|
||||
// Someday this can use ns_bridged. For now, it has to do this.
|
||||
|
@ -2549,8 +2550,9 @@ namespace {
|
|||
|
||||
public:
|
||||
ARCCastChecker(ASTContext &Context, ARCConversionTypeClass source,
|
||||
ARCConversionTypeClass target)
|
||||
: Context(Context), SourceClass(source), TargetClass(target) {}
|
||||
ARCConversionTypeClass target, bool diagnose)
|
||||
: Context(Context), SourceClass(source), TargetClass(target),
|
||||
Diagnose(diagnose) {}
|
||||
|
||||
using super::Visit;
|
||||
ACCResult Visit(Expr *e) {
|
||||
|
@ -2675,14 +2677,15 @@ namespace {
|
|||
if (builtinID == Builtin::BI__builtin___CFStringMakeConstantString)
|
||||
return ACC_bottom;
|
||||
|
||||
// Otherwise, it's +0 unless it follows the create convention.
|
||||
if (ento::coreFoundation::followsCreateRule(fn))
|
||||
return Diagnose ? ACC_plusOne
|
||||
: ACC_invalid; // ACC_plusOne if we start accepting this
|
||||
|
||||
// Otherwise, don't do anything implicit with an unaudited function.
|
||||
if (!fn->hasAttr<CFAuditedTransferAttr>())
|
||||
return ACC_invalid;
|
||||
|
||||
// Otherwise, it's +0 unless it follows the create convention.
|
||||
if (ento::coreFoundation::followsCreateRule(fn))
|
||||
return ACC_invalid; // ACC_plusOne if we start accepting this
|
||||
|
||||
return ACC_plusZero;
|
||||
}
|
||||
|
||||
|
@ -2856,6 +2859,10 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
|
|||
<< castRange
|
||||
<< castExpr->getSourceRange();
|
||||
bool br = S.isKnownName("CFBridgingRelease");
|
||||
bool fCreateRule =
|
||||
ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr)
|
||||
== ACC_plusOne;
|
||||
if (!fCreateRule)
|
||||
{
|
||||
DiagnosticBuilder DiagB = S.Diag(noteLoc, diag::note_arc_bridge);
|
||||
addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
|
||||
|
@ -2884,7 +2891,10 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
|
|||
<< castType
|
||||
<< castRange
|
||||
<< castExpr->getSourceRange();
|
||||
|
||||
bool fCreateRule =
|
||||
ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr)
|
||||
== ACC_plusOne;
|
||||
if (!fCreateRule)
|
||||
{
|
||||
DiagnosticBuilder DiagB = S.Diag(noteLoc, diag::note_arc_bridge);
|
||||
addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
|
||||
|
@ -2965,7 +2975,7 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
|
|||
CCK != CCK_ImplicitConversion)
|
||||
return ACR_okay;
|
||||
|
||||
switch (ARCCastChecker(Context, exprACTC, castACTC).Visit(castExpr)) {
|
||||
switch (ARCCastChecker(Context, exprACTC, castACTC, false).Visit(castExpr)) {
|
||||
// For invalid casts, fall through.
|
||||
case ACC_invalid:
|
||||
break;
|
||||
|
|
|
@ -38,30 +38,27 @@ void to_cf(id obj) {
|
|||
|
||||
CFTypeRef fixits() {
|
||||
id obj1 = (id)CFCreateSomething(); // expected-error{{cast of C pointer type 'CFTypeRef' (aka 'const void *') to Objective-C pointer type 'id' requires a bridged cast}} \
|
||||
// expected-note{{use __bridge to convert directly (no change in ownership)}} \
|
||||
// expected-note{{use CFBridgingRelease call to transfer ownership of a +1 'CFTypeRef' (aka 'const void *') into ARC}}
|
||||
// CHECK: fix-it:"{{.*}}":{40:14-40:14}:"__bridge "
|
||||
// CHECK: fix-it:"{{.*}}":{40:17-40:17}:"CFBridgingRelease("
|
||||
// CHECK: fix-it:"{{.*}}":{40:36-40:36}:")"
|
||||
|
||||
CFTypeRef cf1 = (CFTypeRef)CreateSomething(); // expected-error{{cast of Objective-C pointer type 'id' to C pointer type 'CFTypeRef' (aka 'const void *') requires a bridged cast}} \
|
||||
// expected-note{{use __bridge to convert directly (no change in ownership)}} \
|
||||
// expected-note{{use CFBridgingRetain call to make an ARC object available as a +1 'CFTypeRef' (aka 'const void *')}}
|
||||
// CHECK: fix-it:"{{.*}}":{47:20-47:20}:"__bridge "
|
||||
// CHECK: fix-it:"{{.*}}":{47:30-47:30}:"CFBridgingRetain("
|
||||
// CHECK: fix-it:"{{.*}}":{47:47-47:47}:")"
|
||||
// CHECK: fix-it:"{{.*}}":{45:30-45:30}:"CFBridgingRetain("
|
||||
// CHECK: fix-it:"{{.*}}":{45:47-45:47}:")"
|
||||
|
||||
return (obj1); // expected-error{{implicit conversion of Objective-C pointer type 'id' to C pointer type 'CFTypeRef' (aka 'const void *') requires a bridged cast}} \
|
||||
// expected-note{{use __bridge to convert directly (no change in ownership)}} \
|
||||
// expected-note{{use CFBridgingRetain call to make an ARC object available as a +1 'CFTypeRef' (aka 'const void *')}}
|
||||
// CHECK: fix-it:"{{.*}}":{54:10-54:10}:"(__bridge CFTypeRef)"
|
||||
// CHECK: fix-it:"{{.*}}":{54:10-54:10}:"CFBridgingRetain"
|
||||
// CHECK: fix-it:"{{.*}}":{51:10-51:10}:"(__bridge CFTypeRef)"
|
||||
// CHECK: fix-it:"{{.*}}":{51:10-51:10}:"CFBridgingRetain"
|
||||
}
|
||||
|
||||
CFTypeRef fixitsWithSpace(id obj) {
|
||||
return(obj); // expected-error{{implicit conversion of Objective-C pointer type 'id' to C pointer type 'CFTypeRef' (aka 'const void *') requires a bridged cast}} \
|
||||
// expected-note{{use __bridge to convert directly (no change in ownership)}} \
|
||||
// expected-note{{use CFBridgingRetain call to make an ARC object available as a +1 'CFTypeRef' (aka 'const void *')}}
|
||||
// CHECK: fix-it:"{{.*}}":{62:9-62:9}:"(__bridge CFTypeRef)"
|
||||
// CHECK: fix-it:"{{.*}}":{62:9-62:9}:" CFBridgingRetain"
|
||||
// CHECK: fix-it:"{{.*}}":{59:9-59:9}:"(__bridge CFTypeRef)"
|
||||
// CHECK: fix-it:"{{.*}}":{59:9-59:9}:" CFBridgingRetain"
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ extern CFStringRef CFCreateString0(void);
|
|||
void test0() {
|
||||
id x;
|
||||
x = (id) CFMakeString0(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}}
|
||||
x = (id) CFCreateString0(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}}
|
||||
x = (id) CFCreateString0(); // expected-error {{requires a bridged cast}} expected-note {{CFBridgingRelease call to transfer}}
|
||||
}
|
||||
|
||||
extern CFStringRef CFMakeString1(void) __attribute__((cf_returns_not_retained));
|
||||
|
@ -41,5 +41,5 @@ void test2() {
|
|||
x = (id) CFMakeString2();
|
||||
x = (id) CFCreateString2();
|
||||
x = (id) CFMakeString3(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}}
|
||||
x = (id) CFCreateString3(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}}
|
||||
x = (id) CFCreateString3(); // expected-error {{requires a bridged cast}} expected-note {{CFBridgingRelease call to transfer}}
|
||||
}
|
||||
|
|
|
@ -44,10 +44,10 @@ void test1(int cond) {
|
|||
x = (id) (cond ? (void*) 0 : unauditedString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
|
||||
x = (id) (cond ? (CFStringRef) @"help" : unauditedString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
|
||||
|
||||
x = (id) auditedCreateString(); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
|
||||
x = (id) (cond ? auditedCreateString() : (void*) 0); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
|
||||
x = (id) (cond ? (void*) 0 : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
|
||||
x = (id) (cond ? (CFStringRef) @"help" : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
|
||||
x = (id) auditedCreateString(); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
|
||||
x = (id) (cond ? auditedCreateString() : (void*) 0); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
|
||||
x = (id) (cond ? (void*) 0 : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
|
||||
x = (id) (cond ? (CFStringRef) @"help" : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
|
||||
|
||||
x = (id) [object property];
|
||||
x = (id) (cond ? [object property] : (void*) 0);
|
||||
|
|
|
@ -44,10 +44,10 @@ void test1(int cond) {
|
|||
x = (id) (cond ? (void*) 0 : unauditedString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
|
||||
x = (id) (cond ? (CFStringRef) @"help" : unauditedString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
|
||||
|
||||
x = (id) auditedCreateString(); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
|
||||
x = (id) (cond ? auditedCreateString() : (void*) 0); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
|
||||
x = (id) (cond ? (void*) 0 : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
|
||||
x = (id) (cond ? (CFStringRef) @"help" : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
|
||||
x = (id) auditedCreateString(); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
|
||||
x = (id) (cond ? auditedCreateString() : (void*) 0); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
|
||||
x = (id) (cond ? (void*) 0 : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
|
||||
x = (id) (cond ? (CFStringRef) @"help" : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
|
||||
|
||||
x = (id) [object property];
|
||||
x = (id) (cond ? [object property] : (void*) 0);
|
||||
|
|
Loading…
Reference in New Issue