aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2012-07-27 22:37:07 +0000
committerFariborz Jahanian <fjahanian@apple.com>2012-07-27 22:37:07 +0000
commit533b34fa7bce6aee7a76f962f02afdf022df6d08 (patch)
tree19cabccd66961d787502f62cec98c7ccb8dbc296
parentbbb7af301e0886f109b6391d7ba913b676ef44f5 (diff)
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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160900 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaExprObjC.cpp26
-rw-r--r--test/SemaObjC/arc-bridged-cast.m15
-rw-r--r--test/SemaObjC/arc-cf.m4
-rw-r--r--test/SemaObjC/arc-unbridged-cast.m8
-rw-r--r--test/SemaObjCXX/arc-unbridged-cast.mm8
5 files changed, 34 insertions, 27 deletions
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index bd7f25f6d1..09f12d7ee2 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -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;
diff --git a/test/SemaObjC/arc-bridged-cast.m b/test/SemaObjC/arc-bridged-cast.m
index c8f4d0d166..f115c29255 100644
--- a/test/SemaObjC/arc-bridged-cast.m
+++ b/test/SemaObjC/arc-bridged-cast.m
@@ -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"
}
diff --git a/test/SemaObjC/arc-cf.m b/test/SemaObjC/arc-cf.m
index 69662ea610..8324df6649 100644
--- a/test/SemaObjC/arc-cf.m
+++ b/test/SemaObjC/arc-cf.m
@@ -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}}
}
diff --git a/test/SemaObjC/arc-unbridged-cast.m b/test/SemaObjC/arc-unbridged-cast.m
index 7d5a6b007b..6a39e70771 100644
--- a/test/SemaObjC/arc-unbridged-cast.m
+++ b/test/SemaObjC/arc-unbridged-cast.m
@@ -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);
diff --git a/test/SemaObjCXX/arc-unbridged-cast.mm b/test/SemaObjCXX/arc-unbridged-cast.mm
index 0b3ba07eef..f7d2391487 100644
--- a/test/SemaObjCXX/arc-unbridged-cast.mm
+++ b/test/SemaObjCXX/arc-unbridged-cast.mm
@@ -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);