diff options
author | John McCall <rjmccall@apple.com> | 2011-09-09 05:25:32 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-09-09 05:25:32 +0000 |
commit | 1d9b3b25f7ac0d0195bba6b507a684fe5e7943ee (patch) | |
tree | 0545d4c18cceef895850efe81eac6aa3d054bea7 /lib/AST/Expr.cpp | |
parent | 5e4c80b43fae03bc56b68fe08089e6cffe9ba6fc (diff) |
Give conversions of block pointers to ObjC pointers a different cast kind
than conversions of C pointers to ObjC pointers. In order to ensure that
we've caught every case, add asserts to CastExpr that strictly determine
which cast kind is used for which kind of bit cast.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139352 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Expr.cpp')
-rw-r--r-- | lib/AST/Expr.cpp | 93 |
1 files changed, 91 insertions, 2 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index a3df189a61..25e7de77fb 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -1013,6 +1013,93 @@ SourceRange MemberExpr::getSourceRange() const { return SourceRange(StartLoc, EndLoc); } +void CastExpr::CheckCastConsistency() const { + switch (getCastKind()) { + case CK_DerivedToBase: + case CK_UncheckedDerivedToBase: + case CK_DerivedToBaseMemberPointer: + case CK_BaseToDerived: + case CK_BaseToDerivedMemberPointer: + assert(!path_empty() && "Cast kind should have a base path!"); + break; + + case CK_CPointerToObjCPointerCast: + assert(getType()->isObjCObjectPointerType()); + assert(getSubExpr()->getType()->isPointerType()); + goto CheckNoBasePath; + + case CK_BlockPointerToObjCPointerCast: + assert(getType()->isObjCObjectPointerType()); + assert(getSubExpr()->getType()->isBlockPointerType()); + goto CheckNoBasePath; + + case CK_BitCast: + // Arbitrary casts to C pointer types count as bitcasts. + // Otherwise, we should only have block and ObjC pointer casts + // here if they stay within the type kind. + if (!getType()->isPointerType()) { + assert(getType()->isObjCObjectPointerType() == + getSubExpr()->getType()->isObjCObjectPointerType()); + assert(getType()->isBlockPointerType() == + getSubExpr()->getType()->isBlockPointerType()); + } + goto CheckNoBasePath; + + case CK_AnyPointerToBlockPointerCast: + assert(getType()->isBlockPointerType()); + assert(getSubExpr()->getType()->isAnyPointerType() && + !getSubExpr()->getType()->isBlockPointerType()); + goto CheckNoBasePath; + + // These should not have an inheritance path. + case CK_Dynamic: + case CK_ToUnion: + case CK_ArrayToPointerDecay: + case CK_FunctionToPointerDecay: + case CK_NullToMemberPointer: + case CK_NullToPointer: + case CK_ConstructorConversion: + case CK_IntegralToPointer: + case CK_PointerToIntegral: + case CK_ToVoid: + case CK_VectorSplat: + case CK_IntegralCast: + case CK_IntegralToFloating: + case CK_FloatingToIntegral: + case CK_FloatingCast: + case CK_ObjCObjectLValueCast: + case CK_FloatingRealToComplex: + case CK_FloatingComplexToReal: + case CK_FloatingComplexCast: + case CK_FloatingComplexToIntegralComplex: + case CK_IntegralRealToComplex: + case CK_IntegralComplexToReal: + case CK_IntegralComplexCast: + case CK_IntegralComplexToFloatingComplex: + case CK_ObjCProduceObject: + case CK_ObjCConsumeObject: + case CK_ObjCReclaimReturnedObject: + assert(!getType()->isBooleanType() && "unheralded conversion to bool"); + goto CheckNoBasePath; + + case CK_Dependent: + case CK_LValueToRValue: + case CK_GetObjCProperty: + case CK_NoOp: + case CK_PointerToBoolean: + case CK_IntegralToBoolean: + case CK_FloatingToBoolean: + case CK_MemberPointerToBoolean: + case CK_FloatingComplexToBoolean: + case CK_IntegralComplexToBoolean: + case CK_LValueBitCast: // -> bool& + case CK_UserDefinedConversion: // operator bool() + CheckNoBasePath: + assert(path_empty() && "Cast kind should not have a base path!"); + break; + } +} + const char *CastExpr::getCastKindName() const { switch (getCastKind()) { case CK_Dependent: @@ -1077,8 +1164,10 @@ const char *CastExpr::getCastKindName() const { return "FloatingToBoolean"; case CK_MemberPointerToBoolean: return "MemberPointerToBoolean"; - case CK_AnyPointerToObjCPointerCast: - return "AnyPointerToObjCPointerCast"; + case CK_CPointerToObjCPointerCast: + return "CPointerToObjCPointerCast"; + case CK_BlockPointerToObjCPointerCast: + return "BlockPointerToObjCPointerCast"; case CK_AnyPointerToBlockPointerCast: return "AnyPointerToBlockPointerCast"; case CK_ObjCObjectLValueCast: |