]> granicus.if.org Git - clang/commitdiff
objective-c arc: When function calls with known CFCreate naming convention
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 27 Jul 2012 22:37:07 +0000 (22:37 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 27 Jul 2012 22:37:07 +0000 (22:37 +0000)
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

lib/Sema/SemaExprObjC.cpp
test/SemaObjC/arc-bridged-cast.m
test/SemaObjC/arc-cf.m
test/SemaObjC/arc-unbridged-cast.m
test/SemaObjCXX/arc-unbridged-cast.mm

index bd7f25f6d126dc78965022533a235fa88e135d18..09f12d7ee29d261f8fbebe3a24a0ba703e08e215 100644 (file)
@@ -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;
index c8f4d0d1661af0bc2062bd1ceb1119363cf90ae3..f115c29255825bb53e907530a6c1cd46af4d1629 100644 (file)
@@ -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"
 }
index 69662ea6107832889e1b2c0e7e9eeee2f7b89cf7..8324df66496f04101c184ae51317043e1830554a 100644 (file)
@@ -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}}
 }
index 7d5a6b007b386e0c5466f8adde9b8df844735ee7..6a39e707717ee76a1d50146dd3429ad320bfd992 100644 (file)
@@ -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);
index 0b3ba07eef3e48d0ec838f658fdf1537d7756aeb..f7d2391487042967df3e7c9fada2b86e2cc65373 100644 (file)
@@ -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);