aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-10-28 22:54:28 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-10-28 22:54:28 +0000
commit6ee54925f709176a33aab4727bc35bea2d05aca4 (patch)
treeaab34882c43e0dd83a0793a288e55f2d3bdf5ac4
parent9a8cbc75052d641105e45d0eca2592743fa01e54 (diff)
[ARC] Do not transfer ARC ownership if the cast is going to result in r-value,
in which case the ownership is redundant. Thanks to John for the suggestion. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143240 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaType.cpp12
-rw-r--r--test/SemaObjC/arc-type-conversion.m8
2 files changed, 17 insertions, 3 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index f828b144d6..802b36db07 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -2665,6 +2665,7 @@ static void transferARCOwnershipToDeclaratorChunk(TypeProcessingState &state,
// TODO: mark whether we did this inference?
}
+/// \brief Used for transfering ownership in casts resulting in l-values.
static void transferARCOwnership(TypeProcessingState &state,
QualType &declSpecTy,
Qualifiers::ObjCLifetime ownership) {
@@ -2672,6 +2673,7 @@ static void transferARCOwnership(TypeProcessingState &state,
Declarator &D = state.getDeclarator();
int inner = -1;
+ bool hasIndirection = false;
for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
DeclaratorChunk &chunk = D.getTypeObject(i);
switch (chunk.Kind) {
@@ -2682,11 +2684,15 @@ static void transferARCOwnership(TypeProcessingState &state,
case DeclaratorChunk::Array:
case DeclaratorChunk::Reference:
case DeclaratorChunk::Pointer:
+ if (inner != -1)
+ hasIndirection = true;
inner = i;
break;
case DeclaratorChunk::BlockPointer:
- return transferARCOwnershipToDeclaratorChunk(state, ownership, i);
+ if (inner != -1)
+ transferARCOwnershipToDeclaratorChunk(state, ownership, i);
+ return;
case DeclaratorChunk::Function:
case DeclaratorChunk::MemberPointer:
@@ -2695,13 +2701,13 @@ static void transferARCOwnership(TypeProcessingState &state,
}
if (inner == -1)
- return transferARCOwnershipToDeclSpec(S, declSpecTy, ownership);
+ return;
DeclaratorChunk &chunk = D.getTypeObject(inner);
if (chunk.Kind == DeclaratorChunk::Pointer) {
if (declSpecTy->isObjCRetainableType())
return transferARCOwnershipToDeclSpec(S, declSpecTy, ownership);
- if (declSpecTy->isObjCObjectType())
+ if (declSpecTy->isObjCObjectType() && hasIndirection)
return transferARCOwnershipToDeclaratorChunk(state, ownership, inner);
} else {
assert(chunk.Kind == DeclaratorChunk::Array ||
diff --git a/test/SemaObjC/arc-type-conversion.m b/test/SemaObjC/arc-type-conversion.m
index c626cedcc5..78bb180707 100644
--- a/test/SemaObjC/arc-type-conversion.m
+++ b/test/SemaObjC/arc-type-conversion.m
@@ -77,4 +77,12 @@ void ownership_transfer_in_cast(void *vp, Block *pblk) {
Block_strong blk_strong1;
Block_strong blk_strong2 = (Block)blk_strong1;
Block_autoreleasing *blk_auto = (Block*)pblk;
+
+ id lv;
+ (void)(id)&lv; // expected-error {{cast of an indirect pointer to an Objective-C pointer to 'id'}}
+ (void)(id*)lv; // expected-error {{cast of an Objective-C pointer to '__strong id *'}}
+ (void)(NSString*)&lv; // expected-error {{cast of an indirect pointer to an Objective-C pointer to 'NSString *'}}
+ (void)(NSString**)lv; // expected-error {{cast of an Objective-C pointer to 'NSString *__strong *'}}
+ (void)(Block)&lv; // expected-error {{cast of an indirect pointer to an Objective-C pointer to 'Block'}}
+ (void)(Block*)lv; // expected-error {{cast of an Objective-C pointer to '__strong Block *'}}
}