From: Fariborz Jahanian Date: Tue, 8 Dec 2009 23:09:15 +0000 (+0000) Subject: More detailed analysis of typecast to an objective-c pointer X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=92ef5d75720c032808181133e4d7c5f82230237e;p=clang More detailed analysis of typecast to an objective-c pointer in objective-c++ mode without being too lenient. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90895 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 116d89df97..48bd1e8041 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -1571,7 +1571,11 @@ public: CK_FloatingCast, /// CK_MemberPointerToBoolean - Member pointer to boolean - CK_MemberPointerToBoolean + CK_MemberPointerToBoolean, + + /// CK_AnyPointerToObjCPointerCast - Casting any pointer to objective-c + /// pointer + CK_AnyPointerToObjCPointerCast }; diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 0ad139af4c..f19aa273d9 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -798,6 +798,7 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) { //assert(0 && "Unknown cast kind!"); break; + case CastExpr::CK_AnyPointerToObjCPointerCast: case CastExpr::CK_BitCast: { Value *Src = Visit(const_cast(E)); return Builder.CreateBitCast(Src, ConvertType(DestTy)); diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index c11b5fdd75..f9138902a6 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -539,6 +539,11 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr, return TC_Success; } } + else if (CStyle && DestType->isObjCObjectPointerType()) { + // allow c-style cast of objective-c pointers as they are pervasive. + Kind = CastExpr::CK_AnyPointerToObjCPointerCast; + return TC_Success; + } } } @@ -1053,8 +1058,10 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, return TC_Failed; } - bool destIsPtr = DestType->isPointerType(); - bool srcIsPtr = SrcType->isPointerType(); + bool destIsPtr = + CStyle? DestType->isAnyPointerType() : DestType->isPointerType(); + bool srcIsPtr = + CStyle ? SrcType->isAnyPointerType() : SrcType->isPointerType(); if (!destIsPtr && !srcIsPtr) { // Except for std::nullptr_t->integer and lvalue->reference, which are // handled above, at least one of the two arguments must be a pointer. @@ -1106,7 +1113,11 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, msg = diag::err_bad_cxx_cast_const_away; return TC_Failed; } - + if (CStyle && DestType->isObjCObjectPointerType()) { + Kind = CastExpr::CK_AnyPointerToObjCPointerCast; + return TC_Success; + } + // Not casting away constness, so the only remaining check is for compatible // pointer categories. Kind = CastExpr::CK_BitCast; @@ -1141,7 +1152,6 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, // Void pointers are not specified, but supported by every compiler out there. // So we finish by allowing everything that remains - it's got to be two // object pointers. - Kind = CastExpr::CK_BitCast; return TC_Success; } @@ -1160,10 +1170,6 @@ bool Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr, if (CastTy->isDependentType() || CastExpr->isTypeDependent()) return false; - // allow c-style cast of objective-c pointers as they are pervasive. - if (CastTy->isObjCObjectPointerType()) - return false; - if (!CastTy->isLValueReferenceType() && !CastTy->isRecordType()) DefaultFunctionArrayConversion(CastExpr); diff --git a/test/SemaObjCXX/cstyle-cast.mm b/test/SemaObjCXX/cstyle-cast.mm index 97b7af3133..4682c43e95 100644 --- a/test/SemaObjCXX/cstyle-cast.mm +++ b/test/SemaObjCXX/cstyle-cast.mm @@ -3,7 +3,9 @@ @protocol P @end @interface I @end -int main() { +struct X { X(); }; + +void test1(X x) { void *cft; id oct = (id)cft; @@ -12,9 +14,27 @@ int main() { I* iict = (I*)cft; - id

pid = (id

)cft; + id

qid = (id

)cft; I

*ip = (I

*)cft; + + (id)x; // expected-error {{C-style cast from 'struct X' to 'id' is not allowed}} + + id *pid = (id*)ccct; + + id

*qpid = (id

*)ccct; + + int **pii; + + ccct = (Class)pii; + + qpid = (id

*)pii; + + iict = (I*)pii; + + pii = (int **)ccct; + + pii = (int **)qpid; }