diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2011-07-07 18:55:47 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2011-07-07 18:55:47 +0000 |
commit | 04e5a2509d1eed48cc0c7115c52089bef35b36af (patch) | |
tree | cd9d87daa7bc3725bba7909fab71f6e42b8ce988 | |
parent | 3582a6c0a35f202249b721e100229fde9de0d6a6 (diff) |
objc-arc: diagnose assignment/cast of a weak-unavailable
object to a __weak object/type. // rdar://9732636.
This is objc side of things. objc++ side tbd.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134624 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 5 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 4 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 33 | ||||
-rw-r--r-- | test/SemaObjC/arc-unavailable-for-weakref.m | 19 |
4 files changed, 59 insertions, 2 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index b2301e18d7..2feb043946 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2572,6 +2572,11 @@ def err_arc_weak_no_runtime : Error< "the current deployment target does not support automated __weak references">; def err_arc_unsupported_weak_class : Error< "class is incompatible with __weak references">; +def err_arc_weak_unavailable_assign : Error< + "assignment of a weak-unavailable object to a __weak object">; +def err_arc_cast_of_weak_unavailable : Error< + "cast of weak-unavailable object of type %0 to" + " a __weak object of type %1">; def err_arc_illegal_explicit_message : Error< "ARC forbids explicit message send of %0">; def err_arc_unused_init_message : Error< diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 30719c1c01..8c68a1da44 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -5426,6 +5426,10 @@ public: /// "id <XXX>" = "Foo *", where "Foo *" doesn't implement the XXX protocol. IncompatibleObjCQualifiedId, + /// IncompatibleObjCWeakRef - Assigning a weak-unavailable object to an + /// object with __weak qualifier. + IncompatibleObjCWeakRef, + /// Incompatible - We reject this conversion outright, it is invalid to /// represent it in the AST. Incompatible diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 68b767b474..cf03684c67 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -4065,6 +4065,23 @@ ExprResult Sema::CheckCastTypes(SourceLocation CastStartLoc, SourceRange TyR, return ExprError(); } } + } + else { + QualType canCastType = + Context.getCanonicalType(castType).getUnqualifiedType(); + if (isa<ObjCObjectPointerType>(canCastType) && + castType.getObjCLifetime() == Qualifiers::OCL_Weak && + castExprType->isObjCObjectPointerType()) { + if (const ObjCObjectPointerType *ObjT = + castExprType->getAs<ObjCObjectPointerType>()) + if (ObjT->getInterfaceDecl()->isArcWeakrefUnavailable()) { + Diag(castExpr->getLocStart(), + diag::err_arc_cast_of_weak_unavailable) + << castExprType << castType + << castExpr->getSourceRange(); + return ExprError(); + } + } } } @@ -5124,6 +5141,7 @@ Sema::AssignConvertType Sema::CheckAssignmentConstraints(QualType lhsType, ExprResult &rhs, CastKind &Kind) { QualType rhsType = rhs.get()->getType(); + QualType origLhsType = lhsType; // Get canonical types. We're not formatting these types, just comparing // them. @@ -5278,7 +5296,17 @@ Sema::CheckAssignmentConstraints(QualType lhsType, ExprResult &rhs, // A* -> B* if (rhsType->isObjCObjectPointerType()) { Kind = CK_BitCast; - return checkObjCPointerTypesForAssignment(*this, lhsType, rhsType); + Sema::AssignConvertType result = + checkObjCPointerTypesForAssignment(*this, lhsType, rhsType); + if (getLangOptions().ObjCAutoRefCount && + result == Compatible && + origLhsType.getObjCLifetime() == Qualifiers::OCL_Weak) { + if (const ObjCObjectPointerType *ObjT = + rhsType->getAs<ObjCObjectPointerType>()) + if (ObjT->getInterfaceDecl()->isArcWeakrefUnavailable()) + result = IncompatibleObjCWeakRef; + } + return result; } // int or null -> A* @@ -8679,6 +8707,9 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, case IncompatibleVectors: DiagKind = diag::warn_incompatible_vectors; break; + case IncompatibleObjCWeakRef: + DiagKind = diag::err_arc_weak_unavailable_assign; + break; case Incompatible: DiagKind = diag::err_typecheck_convert_incompatible; isInvalid = true; diff --git a/test/SemaObjC/arc-unavailable-for-weakref.m b/test/SemaObjC/arc-unavailable-for-weakref.m index 07a7e7b975..734fa53472 100644 --- a/test/SemaObjC/arc-unavailable-for-weakref.m +++ b/test/SemaObjC/arc-unavailable-for-weakref.m @@ -14,5 +14,22 @@ int main() { id obj; - ns1 = (__weak sub *)obj; // expected-error {{class is incompatible with __weak references}} + ns1 = (__weak sub *)obj; // expected-error {{assignment of a weak-unavailable object to a __weak object}} \ + // expected-error {{class is incompatible with __weak references}} } + +// rdar://9732636 +__attribute__((objc_arc_weak_reference_unavailable)) +@interface NOWEAK ++ (id) new; +@end + +NOWEAK * Test9732636() { + NOWEAK * strong1 = [NOWEAK new]; + __weak id weak1; + weak1 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}} + + __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'}} +} + |