From 244b187d2221b8377295c311d2b79be5aa483af3 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Sat, 29 Oct 2011 00:06:10 +0000 Subject: [PATCH] objc-arc: desugar certain type and improve on diagnostic for ownership qualifier cast which won't work. // rdar://10244607 llvm-svn: 143258 --- .../clang/Basic/DiagnosticSemaKinds.td | 3 +- clang/lib/Sema/SemaExprObjC.cpp | 30 ++++++++++++------- clang/test/SemaObjC/arc-objc-lifetime.m | 6 ++-- .../SemaObjC/arc-unavailable-for-weakref.m | 6 ++-- .../SemaObjCXX/arc-unavailable-for-weakref.mm | 6 ++-- 5 files changed, 31 insertions(+), 20 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 633da42b587e..4c1e868548fb 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3043,8 +3043,7 @@ def err_arc_mismatched_cast : Error< "an Objective-C pointer|an indirect pointer to an Objective-C pointer}1" " to %3 is disallowed with ARC">; def err_arc_nolifetime_behavior : Error< - "casting expression of type %1 to type %0 with qualified lifetime" - "will not change object lifetime">; + "explicit ownership qualifier on cast result would have no effect">; def err_arc_objc_object_in_struct : Error< "ARC forbids Objective-C objects in structs or unions">; def err_arc_objc_property_default_assign_on_object : Error< diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index edf8b720504e..019dc817643d 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -1937,17 +1937,27 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType, if (exprACTC == castACTC) { // check for viablity and report error if casting an rvalue to a // life-time qualifier. - if ((castACTC == ACTC_retainable) && - isa(castType) && - (castType.getObjCLifetime() != Qualifiers::OCL_None) && + if ((castACTC == ACTC_retainable) && (CCK == CCK_CStyleCast || CCK == CCK_OtherCast) && - castType != castExprType) { - SourceLocation loc = - (castRange.isValid() ? castRange.getBegin() - : castExpr->getExprLoc()); - Diag(loc, diag::err_arc_nolifetime_behavior) - << effCastType << castExprType - << castRange << castExpr->getSourceRange(); + (castType != castExprType)) { + const Type *DT = castType.getTypePtr(); + QualType QDT = castType; + // We desugar some types but not others. We ignore those + // that cannot happen in a cast; i.e. auto, and those which + // should not be de-sugared; i.e typedef. + if (const ParenType *PT = dyn_cast(DT)) + QDT = PT->desugar(); + else if (const TypeOfType *TP = dyn_cast(DT)) + QDT = TP->desugar(); + else if (const AttributedType *AT = dyn_cast(DT)) + QDT = AT->desugar(); + if (QDT != castType && + QDT.getObjCLifetime() != Qualifiers::OCL_None) { + SourceLocation loc = + (castRange.isValid() ? castRange.getBegin() + : castExpr->getExprLoc()); + Diag(loc, diag::err_arc_nolifetime_behavior); + } } return ACR_okay; } diff --git a/clang/test/SemaObjC/arc-objc-lifetime.m b/clang/test/SemaObjC/arc-objc-lifetime.m index 19073c08c060..2318fbfccd57 100644 --- a/clang/test/SemaObjC/arc-objc-lifetime.m +++ b/clang/test/SemaObjC/arc-objc-lifetime.m @@ -17,12 +17,14 @@ typedef __autoreleasing NSString * AUTORELEASEPNSString; - (CFStringRef)myString { CFStringRef myString = - (__bridge CFStringRef) (__strong NSString *)CFBridgingRelease(); // expected-error {{casting expression of type 'NSString *' to type 'NSString *__strong' with qualified lifetimewill not change object lifetime}} + (__bridge CFStringRef) (__strong NSString *)CFBridgingRelease(); // expected-error {{explicit ownership qualifier on cast result would have no effect}} myString = - (__bridge CFStringRef) (__autoreleasing PNSString) CFBridgingRelease(); // expected-error {{casting expression of type 'NSString *' to type '__autoreleasing PNSString' (aka 'NSString *__autoreleasing') with qualified lifetimewill not change object}} + (__bridge CFStringRef) (__autoreleasing PNSString) CFBridgingRelease(); // expected-error {{explicit ownership qualifier on cast result would have no effect}} myString = (__bridge CFStringRef) (AUTORELEASEPNSString) CFBridgingRelease(); // OK + myString = + (__bridge CFStringRef) (typeof(__strong NSString *)) CFBridgingRelease(); // expected-error {{explicit ownership qualifier on cast result would have no effect}} return myString; } diff --git a/clang/test/SemaObjC/arc-unavailable-for-weakref.m b/clang/test/SemaObjC/arc-unavailable-for-weakref.m index 712ccf4a115d..210727ad39fd 100644 --- a/clang/test/SemaObjC/arc-unavailable-for-weakref.m +++ b/clang/test/SemaObjC/arc-unavailable-for-weakref.m @@ -16,7 +16,7 @@ int main() { ns1 = (__weak sub *)obj; // expected-error {{assignment of a weak-unavailable object to a __weak object}} \ // expected-error {{class is incompatible with __weak references}} \ - // expected-error {{casting expression of type 'id' to type 'sub *__weak' with qualified lifetimewill not change object lifetime}} + // expected-error {{explicit ownership qualifier on cast result would have no effect}} } // rdar://9732636 @@ -32,7 +32,7 @@ NOWEAK * Test1() { __weak id weak2 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}} return (__weak id)strong1; // expected-error {{cast of weak-unavailable object of type 'NOWEAK *' to a __weak object of type '__weak id'}} \ - // expected-error {{casting expression of type 'NOWEAK *' to type '__weak id' with qualified lifetimewill not change object lifetime}} + // expected-error {{explicit ownership qualifier on cast result would have no effect}} } @protocol P @end @@ -45,6 +45,6 @@ NOWEAK * Test2() { __weak id

weak2 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}} return (__weak id

)strong1; // expected-error {{cast of weak-unavailable object of type 'NOWEAK *' to a __weak object of type '__weak id

'}} \ - // expected-error {{casting expression of type 'NOWEAK *' to type '__weak id

' with qualified lifetimewill not change object lifetime}} + // expected-error {{explicit ownership qualifier on cast result would have no effect}} } diff --git a/clang/test/SemaObjCXX/arc-unavailable-for-weakref.mm b/clang/test/SemaObjCXX/arc-unavailable-for-weakref.mm index 74fdd54d48e3..2347061cfdb3 100644 --- a/clang/test/SemaObjCXX/arc-unavailable-for-weakref.mm +++ b/clang/test/SemaObjCXX/arc-unavailable-for-weakref.mm @@ -16,7 +16,7 @@ int main() { ns1 = (__weak sub *)obj; // expected-error {{assignment of a weak-unavailable object to a __weak object}} \ // expected-error {{class is incompatible with __weak references}} \ - // expected-error {{casting expression of type 'id' to type 'sub *__weak' with qualified lifetimewill not change object lifetime}} + // expected-error {{explicit ownership qualifier on cast result would have no effect}} } // rdar://9732636 @@ -32,7 +32,7 @@ NOWEAK * Test1() { __weak id weak2 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}} return (__weak id)strong1; // expected-error {{cast of weak-unavailable object of type 'NOWEAK *' to a __weak object of type '__weak id'}} \ - // expected-error {{casting expression of type 'NOWEAK *' to type '__weak id' with qualified lifetimewill not change object lifetime}} + // expected-error {{explicit ownership qualifier on cast result would have no effect}} } @protocol P @end @@ -45,6 +45,6 @@ NOWEAK * Test2() { __weak id

weak2 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}} return (__weak id)strong1; // expected-error {{cast of weak-unavailable object of type 'NOWEAK *' to a __weak object of type '__weak id'}} \ - // expected-error {{casting expression of type 'NOWEAK *' to type '__weak id' with qualified lifetimewill not change object lifetime}} + // expected-error {{explicit ownership qualifier on cast result would have no effect}} }