summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-09-09 05:25:32 +0000
committerJohn McCall <rjmccall@apple.com>2011-09-09 05:25:32 +0000
commit9320b87cff21e87752c5b511ba49aaead5d5792c (patch)
tree47977c15fd7ca50d320cb73f624a0d5010ecad86 /clang/lib/Sema/SemaExpr.cpp
parent10162ab7edce78aab8c9943b0c15eef4a4115db0 (diff)
downloadbcm5719-llvm-9320b87cff21e87752c5b511ba49aaead5d5792c.tar.gz
bcm5719-llvm-9320b87cff21e87752c5b511ba49aaead5d5792c.zip
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. llvm-svn: 139352
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp96
1 files changed, 59 insertions, 37 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index d20dee44d3d..f10bb3413cb 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -3808,16 +3808,26 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) {
if (S.Context.hasSameUnqualifiedType(SrcTy, DestTy))
return CK_NoOp;
- switch (SrcTy->getScalarTypeKind()) {
+ switch (Type::ScalarTypeKind SrcKind = SrcTy->getScalarTypeKind()) {
case Type::STK_MemberPointer:
llvm_unreachable("member pointer type in C");
- case Type::STK_Pointer:
+ case Type::STK_CPointer:
+ case Type::STK_BlockPointer:
+ case Type::STK_ObjCObjectPointer:
switch (DestTy->getScalarTypeKind()) {
- case Type::STK_Pointer:
- return DestTy->isObjCObjectPointerType() ?
- CK_AnyPointerToObjCPointerCast :
- CK_BitCast;
+ case Type::STK_CPointer:
+ return CK_BitCast;
+ case Type::STK_BlockPointer:
+ return (SrcKind == Type::STK_BlockPointer
+ ? CK_BitCast : CK_AnyPointerToBlockPointerCast);
+ case Type::STK_ObjCObjectPointer:
+ if (SrcKind == Type::STK_ObjCObjectPointer)
+ return CK_BitCast;
+ else if (SrcKind == Type::STK_CPointer)
+ return CK_CPointerToObjCPointerCast;
+ else
+ return CK_BlockPointerToObjCPointerCast;
case Type::STK_Bool:
return CK_PointerToBoolean;
case Type::STK_Integral:
@@ -3833,7 +3843,9 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) {
case Type::STK_Bool: // casting from bool is like casting from an integer
case Type::STK_Integral:
switch (DestTy->getScalarTypeKind()) {
- case Type::STK_Pointer:
+ case Type::STK_CPointer:
+ case Type::STK_ObjCObjectPointer:
+ case Type::STK_BlockPointer:
if (Src.get()->isNullPointerConstant(S.Context,
Expr::NPC_ValueDependentIsNull))
return CK_NullToPointer;
@@ -3877,7 +3889,9 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) {
DestTy->getAs<ComplexType>()->getElementType(),
CK_FloatingToIntegral);
return CK_IntegralRealToComplex;
- case Type::STK_Pointer:
+ case Type::STK_CPointer:
+ case Type::STK_ObjCObjectPointer:
+ case Type::STK_BlockPointer:
llvm_unreachable("valid float->pointer cast?");
case Type::STK_MemberPointer:
llvm_unreachable("member pointer type in C");
@@ -3904,7 +3918,9 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) {
SrcTy->getAs<ComplexType>()->getElementType(),
CK_FloatingComplexToReal);
return CK_FloatingToIntegral;
- case Type::STK_Pointer:
+ case Type::STK_CPointer:
+ case Type::STK_ObjCObjectPointer:
+ case Type::STK_BlockPointer:
llvm_unreachable("valid complex float->pointer cast?");
case Type::STK_MemberPointer:
llvm_unreachable("member pointer type in C");
@@ -3931,7 +3947,9 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) {
SrcTy->getAs<ComplexType>()->getElementType(),
CK_IntegralComplexToReal);
return CK_IntegralToFloating;
- case Type::STK_Pointer:
+ case Type::STK_CPointer:
+ case Type::STK_ObjCObjectPointer:
+ case Type::STK_BlockPointer:
llvm_unreachable("valid complex int->pointer cast?");
case Type::STK_MemberPointer:
llvm_unreachable("member pointer type in C");
@@ -3940,7 +3958,6 @@ static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) {
}
llvm_unreachable("Unhandled scalar cast");
- return CK_BitCast;
}
/// CheckCastTypes - Check type constraints for casting between types.
@@ -4497,12 +4514,12 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS,
QualType lhptee, rhptee;
// Get the pointee types.
- if (LHSTy->isBlockPointerType()) {
- lhptee = LHSTy->getAs<BlockPointerType>()->getPointeeType();
- rhptee = RHSTy->getAs<BlockPointerType>()->getPointeeType();
+ if (const BlockPointerType *LHSBTy = LHSTy->getAs<BlockPointerType>()) {
+ lhptee = LHSBTy->getPointeeType();
+ rhptee = RHSTy->castAs<BlockPointerType>()->getPointeeType();
} else {
- lhptee = LHSTy->getAs<PointerType>()->getPointeeType();
- rhptee = RHSTy->getAs<PointerType>()->getPointeeType();
+ lhptee = LHSTy->castAs<PointerType>()->getPointeeType();
+ rhptee = RHSTy->castAs<PointerType>()->getPointeeType();
}
if (!S.Context.typesAreCompatible(lhptee.getUnqualifiedType(),
@@ -4752,23 +4769,23 @@ QualType Sema::FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS,
// redefinition type if an attempt is made to access its fields.
if (LHSTy->isObjCClassType() &&
(Context.hasSameType(RHSTy, Context.getObjCClassRedefinitionType()))) {
- RHS = ImpCastExprToType(RHS.take(), LHSTy, CK_BitCast);
+ RHS = ImpCastExprToType(RHS.take(), LHSTy, CK_CPointerToObjCPointerCast);
return LHSTy;
}
if (RHSTy->isObjCClassType() &&
(Context.hasSameType(LHSTy, Context.getObjCClassRedefinitionType()))) {
- LHS = ImpCastExprToType(LHS.take(), RHSTy, CK_BitCast);
+ LHS = ImpCastExprToType(LHS.take(), RHSTy, CK_CPointerToObjCPointerCast);
return RHSTy;
}
// And the same for struct objc_object* / id
if (LHSTy->isObjCIdType() &&
(Context.hasSameType(RHSTy, Context.getObjCIdRedefinitionType()))) {
- RHS = ImpCastExprToType(RHS.take(), LHSTy, CK_BitCast);
+ RHS = ImpCastExprToType(RHS.take(), LHSTy, CK_CPointerToObjCPointerCast);
return LHSTy;
}
if (RHSTy->isObjCIdType() &&
(Context.hasSameType(LHSTy, Context.getObjCIdRedefinitionType()))) {
- LHS = ImpCastExprToType(LHS.take(), RHSTy, CK_BitCast);
+ LHS = ImpCastExprToType(LHS.take(), RHSTy, CK_CPointerToObjCPointerCast);
return RHSTy;
}
// And the same for struct objc_selector* / SEL
@@ -4789,8 +4806,8 @@ QualType Sema::FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS,
// Two identical object pointer types are always compatible.
return LHSTy;
}
- const ObjCObjectPointerType *LHSOPT = LHSTy->getAs<ObjCObjectPointerType>();
- const ObjCObjectPointerType *RHSOPT = RHSTy->getAs<ObjCObjectPointerType>();
+ const ObjCObjectPointerType *LHSOPT = LHSTy->castAs<ObjCObjectPointerType>();
+ const ObjCObjectPointerType *RHSOPT = RHSTy->castAs<ObjCObjectPointerType>();
QualType compositeType = LHSTy;
// If both operands are interfaces and either operand can be
@@ -5356,7 +5373,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
if (isa<ObjCObjectPointerType>(RHSType)) {
// - conversions to void*
if (LHSPointer->getPointeeType()->isVoidType()) {
- Kind = CK_AnyPointerToObjCPointerCast;
+ Kind = CK_BitCast;
return Compatible;
}
@@ -5387,7 +5404,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
if (isa<BlockPointerType>(LHSType)) {
// U^ -> T^
if (RHSType->isBlockPointerType()) {
- Kind = CK_AnyPointerToBlockPointerCast;
+ Kind = CK_BitCast;
return checkBlockPointerTypesForAssignment(*this, LHSType, RHSType);
}
@@ -5436,9 +5453,10 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
// In general, C pointers are not compatible with ObjC object pointers,
// with two exceptions:
if (isa<PointerType>(RHSType)) {
+ Kind = CK_CPointerToObjCPointerCast;
+
// - conversions from 'void*'
if (RHSType->isVoidPointerType()) {
- Kind = CK_AnyPointerToObjCPointerCast;
return Compatible;
}
@@ -5446,17 +5464,15 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
if (LHSType->isObjCClassType() &&
Context.hasSameType(RHSType,
Context.getObjCClassRedefinitionType())) {
- Kind = CK_BitCast;
return Compatible;
}
- Kind = CK_AnyPointerToObjCPointerCast;
return IncompatiblePointer;
}
// T^ -> A*
if (RHSType->isBlockPointerType()) {
- Kind = CK_AnyPointerToObjCPointerCast;
+ Kind = CK_BlockPointerToObjCPointerCast;
return Compatible;
}
@@ -5553,7 +5569,7 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType,
// 1) void pointer
// 2) null pointer constant
if (RHSType->isPointerType())
- if (RHSType->getAs<PointerType>()->getPointeeType()->isVoidType()) {
+ if (RHSType->castAs<PointerType>()->getPointeeType()->isVoidType()) {
RHS = ImpCastExprToType(RHS.take(), it->getType(), CK_BitCast);
InitField = *it;
break;
@@ -6452,9 +6468,9 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
// when handling null pointer constants.
if (LHSType->isPointerType() && RHSType->isPointerType()) { // C99 6.5.8p2
QualType LCanPointeeTy =
- Context.getCanonicalType(LHSType->getAs<PointerType>()->getPointeeType());
+ LHSType->castAs<PointerType>()->getPointeeType().getCanonicalType();
QualType RCanPointeeTy =
- Context.getCanonicalType(RHSType->getAs<PointerType>()->getPointeeType());
+ RHSType->castAs<PointerType>()->getPointeeType().getCanonicalType();
if (getLangOptions().CPlusPlus) {
if (LCanPointeeTy == RCanPointeeTy)
@@ -6560,8 +6576,8 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
// Handle block pointer types.
if (!IsRelational && LHSType->isBlockPointerType() &&
RHSType->isBlockPointerType()) {
- QualType lpointee = LHSType->getAs<BlockPointerType>()->getPointeeType();
- QualType rpointee = RHSType->getAs<BlockPointerType>()->getPointeeType();
+ QualType lpointee = LHSType->castAs<BlockPointerType>()->getPointeeType();
+ QualType rpointee = RHSType->castAs<BlockPointerType>()->getPointeeType();
if (!LHSIsNull && !RHSIsNull &&
!Context.typesAreCompatible(lpointee, rpointee)) {
@@ -6587,9 +6603,13 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
<< RHS.get()->getSourceRange();
}
if (LHSIsNull && !RHSIsNull)
- LHS = ImpCastExprToType(LHS.take(), RHSType, CK_BitCast);
+ LHS = ImpCastExprToType(LHS.take(), RHSType,
+ RHSType->isPointerType() ? CK_BitCast
+ : CK_AnyPointerToBlockPointerCast);
else
- RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast);
+ RHS = ImpCastExprToType(RHS.take(), LHSType,
+ LHSType->isPointerType() ? CK_BitCast
+ : CK_AnyPointerToBlockPointerCast);
return ResultTy;
}
@@ -6607,9 +6627,11 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
/*isError*/false);
}
if (LHSIsNull && !RHSIsNull)
- LHS = ImpCastExprToType(LHS.take(), RHSType, CK_BitCast);
+ LHS = ImpCastExprToType(LHS.take(), RHSType,
+ RPT ? CK_BitCast :CK_CPointerToObjCPointerCast);
else
- RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast);
+ RHS = ImpCastExprToType(RHS.take(), LHSType,
+ LPT ? CK_BitCast :CK_CPointerToObjCPointerCast);
return ResultTy;
}
if (LHSType->isObjCObjectPointerType() &&
OpenPOWER on IntegriCloud