mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 12:26:52 +08:00
objc++-arc: diagnose assignment/cast of a weak-unavailable
object to a __weak object/type. // rdar://9732636. One item is yet todo. llvm-svn: 134655
This commit is contained in:
@@ -5626,6 +5626,9 @@ public:
|
||||
/// retainable pointers and other pointer kinds.
|
||||
void CheckObjCARCConversion(SourceRange castRange, QualType castType,
|
||||
Expr *&op, CheckedConversionKind CCK);
|
||||
|
||||
bool CheckObjCARCUnavailableWeakConversion(QualType castType,
|
||||
QualType ExprType);
|
||||
|
||||
/// checkRetainCycles - Check whether an Objective-C message send
|
||||
/// might create an obvious retain cycle.
|
||||
|
||||
@@ -1717,7 +1717,8 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK,
|
||||
Kind = CK_Dependent;
|
||||
return Owned(CastExpr);
|
||||
}
|
||||
|
||||
|
||||
QualType origCastExprType = CastExpr->getType();
|
||||
if (VK == VK_RValue && !CastTy->isRecordType()) {
|
||||
ExprResult CastExprRes = DefaultFunctionArrayLvalueConversion(CastExpr);
|
||||
if (CastExprRes.isInvalid())
|
||||
@@ -1773,8 +1774,15 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK,
|
||||
}
|
||||
}
|
||||
|
||||
if (getLangOptions().ObjCAutoRefCount && tcr == TC_Success)
|
||||
if (getLangOptions().ObjCAutoRefCount && tcr == TC_Success) {
|
||||
CheckObjCARCConversion(R, CastTy, CastExpr, CCK);
|
||||
if (!CheckObjCARCUnavailableWeakConversion(CastTy,
|
||||
origCastExprType))
|
||||
Diag(CastExpr->getLocStart(),
|
||||
diag::err_arc_cast_of_weak_unavailable)
|
||||
<< origCastExprType << CastTy
|
||||
<< CastExpr->getSourceRange();
|
||||
}
|
||||
|
||||
if (tcr != TC_Success && msg != 0) {
|
||||
if (CastExpr->getType() == Context.OverloadTy) {
|
||||
|
||||
@@ -4066,22 +4066,12 @@ ExprResult Sema::CheckCastTypes(SourceLocation CastStartLoc, SourceRange TyR,
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
else if (!CheckObjCARCUnavailableWeakConversion(castType, castExprType)) {
|
||||
Diag(castExpr->getLocStart(),
|
||||
diag::err_arc_cast_of_weak_unavailable)
|
||||
<< castExprType << castType
|
||||
<< castExpr->getSourceRange();
|
||||
return ExprError();
|
||||
}
|
||||
}
|
||||
return ExprError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5300,12 +5290,8 @@ Sema::CheckAssignmentConstraints(QualType lhsType, ExprResult &rhs,
|
||||
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;
|
||||
}
|
||||
!CheckObjCARCUnavailableWeakConversion(origLhsType, rhsType))
|
||||
result = IncompatibleObjCWeakRef;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -5474,8 +5460,12 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, ExprResult &rExpr) {
|
||||
AA_Assigning);
|
||||
if (Res.isInvalid())
|
||||
return Incompatible;
|
||||
Sema::AssignConvertType result = Compatible;
|
||||
if (getLangOptions().ObjCAutoRefCount &&
|
||||
!CheckObjCARCUnavailableWeakConversion(lhsType, rExpr.get()->getType()))
|
||||
result = IncompatibleObjCWeakRef;
|
||||
rExpr = move(Res);
|
||||
return Compatible;
|
||||
return result;
|
||||
}
|
||||
|
||||
// FIXME: Currently, we fall through and treat C++ classes like C
|
||||
|
||||
@@ -1771,6 +1771,23 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
|
||||
<< castRange << castExpr->getSourceRange();
|
||||
}
|
||||
|
||||
bool Sema::CheckObjCARCUnavailableWeakConversion(QualType castType,
|
||||
QualType exprType) {
|
||||
QualType canCastType =
|
||||
Context.getCanonicalType(castType).getUnqualifiedType();
|
||||
QualType canExprType =
|
||||
Context.getCanonicalType(exprType).getUnqualifiedType();
|
||||
if (isa<ObjCObjectPointerType>(canCastType) &&
|
||||
castType.getObjCLifetime() == Qualifiers::OCL_Weak &&
|
||||
canExprType->isObjCObjectPointerType()) {
|
||||
if (const ObjCObjectPointerType *ObjT =
|
||||
canExprType->getAs<ObjCObjectPointerType>())
|
||||
if (ObjT->getInterfaceDecl()->isArcWeakrefUnavailable())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Look for an ObjCReclaimReturnedObject cast and destroy it.
|
||||
static Expr *maybeUndoReclaimObject(Expr *e) {
|
||||
// For now, we just undo operands that are *immediately* reclaim
|
||||
|
||||
36
clang/test/SemaObjCXX/arc-unavailable-for-weakref.mm
Normal file
36
clang/test/SemaObjCXX/arc-unavailable-for-weakref.mm
Normal file
@@ -0,0 +1,36 @@
|
||||
// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin11 -fobjc-nonfragile-abi -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify %s
|
||||
// rdar://9693477
|
||||
|
||||
__attribute__((objc_arc_weak_reference_unavailable))
|
||||
@interface NSOptOut1072 // expected-note {{class is declared here}}
|
||||
@end
|
||||
|
||||
@interface sub : NSOptOut1072 @end // expected-note 2 {{class is declared here}}
|
||||
|
||||
int main() {
|
||||
__weak sub *w2; // expected-error {{class is incompatible with __weak references}}
|
||||
|
||||
__weak NSOptOut1072 *ns1; // expected-error {{class is incompatible with __weak references}}
|
||||
|
||||
id obj;
|
||||
|
||||
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}}
|
||||
|
||||
// FIXME. NYI.
|
||||
__weak id weak2 = strong1; // expected-FIXME {{assignment of a weak-unavailable object to a __weak object}}
|
||||
return (__weak id)strong1; // expected-error {{cast of weak-unavailable object of type 'NOWEAK *__strong' to a __weak object of type '__weak id'}}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user