[cfe-commits] r161187 - in /cfe/trunk: lib/Sema/SemaPseudoObject.cpp test/SemaObjC/arc-dict-bridged-cast.m
Jordan Rose
jordan_rose at apple.com
Thu Aug 2 11:21:26 PDT 2012
That is a really ugly fixit: (__bridge __strong id <NSCopying>). At the very least we should drop the __strong, but I could see an argument for just offering (__bridge id). That's all the type info we get with CFBridgingRelease, and it's not like we need more info to type-check here (since they're already casting).
Stepping back, this is another case where we know the ownership semantics and should only offer one of the fixits. I assume this commit will already do the right thing if CFStringCreateMutable were annotated with cf_audited_transfer / arc_cf_code_audited, but maybe we should explicitly add that to the test?
Jordan
On Aug 2, 2012, at 11:03 , Fariborz Jahanian <fjahanian at apple.com> wrote:
> Author: fjahanian
> Date: Thu Aug 2 13:03:58 2012
> New Revision: 161187
>
> URL: http://llvm.org/viewvc/llvm-project?rev=161187&view=rev
> Log:
> objective-c arc: Patch to suggest bridge casting of CF
> objects used as dictionary subscript objects.
> // rdar://11913153
>
> Added:
> cfe/trunk/test/SemaObjC/arc-dict-bridged-cast.m
> Modified:
> cfe/trunk/lib/Sema/SemaPseudoObject.cpp
>
> Modified: cfe/trunk/lib/Sema/SemaPseudoObject.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaPseudoObject.cpp?rev=161187&r1=161186&r2=161187&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaPseudoObject.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaPseudoObject.cpp Thu Aug 2 13:03:58 2012
> @@ -955,6 +955,27 @@
> return OS_Error;
> }
>
> +/// CheckKeyForObjCARCConversion - This routine suggests bridge casting of CF
> +/// objects used as dictionary subscript key objects.
> +static void CheckKeyForObjCARCConversion(Sema &S, QualType ContainerT,
> + Expr *Key) {
> + if (ContainerT.isNull())
> + return;
> + // dictionary subscripting.
> + // - (id)objectForKeyedSubscript:(id)key;
> + IdentifierInfo *KeyIdents[] = {
> + &S.Context.Idents.get("objectForKeyedSubscript")
> + };
> + Selector GetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
> + ObjCMethodDecl *Getter = S.LookupMethodInObjectType(GetterSelector, ContainerT,
> + true /*instance*/);
> + if (!Getter)
> + return;
> + QualType T = Getter->param_begin()[0]->getType();
> + S.CheckObjCARCConversion(Key->getSourceRange(),
> + T, Key, Sema::CCK_ImplicitConversion);
> +}
> +
> bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
> if (AtIndexGetter)
> return true;
> @@ -972,8 +993,12 @@
> }
> Sema::ObjCSubscriptKind Res =
> S.CheckSubscriptingKind(RefExpr->getKeyExpr());
> - if (Res == Sema::OS_Error)
> + if (Res == Sema::OS_Error) {
> + if (S.getLangOpts().ObjCAutoRefCount)
> + CheckKeyForObjCARCConversion(S, ResultType,
> + RefExpr->getKeyExpr());
> return false;
> + }
> bool arrayRef = (Res == Sema::OS_Array);
>
> if (ResultType.isNull()) {
> @@ -1080,8 +1105,12 @@
>
> Sema::ObjCSubscriptKind Res =
> S.CheckSubscriptingKind(RefExpr->getKeyExpr());
> - if (Res == Sema::OS_Error)
> + if (Res == Sema::OS_Error) {
> + if (S.getLangOpts().ObjCAutoRefCount)
> + CheckKeyForObjCARCConversion(S, ResultType,
> + RefExpr->getKeyExpr());
> return false;
> + }
> bool arrayRef = (Res == Sema::OS_Array);
>
> if (ResultType.isNull()) {
>
> Added: cfe/trunk/test/SemaObjC/arc-dict-bridged-cast.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc-dict-bridged-cast.m?rev=161187&view=auto
> ==============================================================================
> --- cfe/trunk/test/SemaObjC/arc-dict-bridged-cast.m (added)
> +++ cfe/trunk/test/SemaObjC/arc-dict-bridged-cast.m Thu Aug 2 13:03:58 2012
> @@ -0,0 +1,47 @@
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify %s
> +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
> +// rdar://11913153
> +
> +typedef const struct __CFString * CFStringRef;
> +typedef struct __CFString * CFMutableStringRef;
> +typedef signed long CFIndex;
> +typedef const struct __CFAllocator * CFAllocatorRef;
> +
> +extern const CFStringRef kCFBundleNameKey;
> +
> + at protocol NSCopying @end
> +
> + at interface NSDictionary
> +- (id)objectForKeyedSubscript:(id<NSCopying>)key;
> + at end
> +
> +extern
> +CFMutableStringRef CFStringCreateMutable(CFAllocatorRef alloc, CFIndex maxLength);
> +
> +typedef const void * CFTypeRef;
> +
> +id CFBridgingRelease(CFTypeRef __attribute__((cf_consumed)) X);
> +
> + at interface NSMutableString @end
> +
> +NSMutableString *test() {
> + NSDictionary *infoDictionary;
> + infoDictionary[kCFBundleNameKey] = 0; // expected-error {{indexing expression is invalid because subscript type 'CFStringRef' (aka 'const struct __CFString *') is not an integral or Objective-C pointer type}} \
> + // expected-error {{implicit conversion of C pointer type 'CFStringRef' (aka 'const struct __CFString *') to Objective-C pointer type '__strong id<NSCopying>' 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 'CFStringRef' (aka 'const struct __CFString *') into ARC}}
> + return infoDictionary[CFStringCreateMutable(((void*)0), 100)]; // expected-error {{indexing expression is invalid because subscript type 'CFMutableStringRef' (aka 'struct __CFString *') is not an integral or Objective-C pointer type}} \
> + // expected-error {{implicit conversion of C pointer type 'CFMutableStringRef' (aka 'struct __CFString *') to Objective-C pointer type '__strong id<NSCopying>' 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 'CFMutableStringRef' (aka 'struct __CFString *') into ARC}}
> +
> +}
> +
> +// CHECK: fix-it:"{{.*}}":{29:18-29:18}:"(__bridge __strong id<NSCopying>)("
> +// CHECK: fix-it:"{{.*}}":{29:34-29:34}:")"
> +// CHECK: fix-it:"{{.*}}":{29:18-29:18}:"CFBridgingRelease("
> +// CHECK: fix-it:"{{.*}}":{29:34-29:34}:")"
> +// CHECK: fix-it:"{{.*}}":{33:25-33:25}:"(__bridge __strong id<NSCopying>)("
> +// CHECK: fix-it:"{{.*}}":{33:63-33:63}:")"
> +// CHECK: fix-it:"{{.*}}":{33:25-33:25}:"CFBridgingRelease("
> +// CHECK: fix-it:"{{.*}}":{33:63-33:63}:")"
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list