diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Sema/SemaType.cpp | 12 | ||||
| -rw-r--r-- | clang/test/SemaObjC/arc-type-conversion.m | 8 | 
2 files changed, 17 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index f828b144d6c..802b36db078 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/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/clang/test/SemaObjC/arc-type-conversion.m b/clang/test/SemaObjC/arc-type-conversion.m index c626cedcc5e..78bb180707f 100644 --- a/clang/test/SemaObjC/arc-type-conversion.m +++ b/clang/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 *'}}  }  | 

