When comparing a null pointer and something else, always cast the null

pointer instead of the other operand.

llvm-svn: 127458
This commit is contained in:
John McCall 2011-03-11 04:25:25 +00:00
parent 9575d8446c
commit 7684ddee7c
1 changed files with 26 additions and 15 deletions

View File

@ -6965,8 +6965,12 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers) Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
<< lType << rType << lex->getSourceRange() << rex->getSourceRange(); << lType << rType << lex->getSourceRange() << rex->getSourceRange();
} }
if (LCanPointeeTy != RCanPointeeTy) if (LCanPointeeTy != RCanPointeeTy) {
ImpCastExprToType(rex, lType, CK_BitCast); if (LHSIsNull && !RHSIsNull)
ImpCastExprToType(lex, rType, CK_BitCast);
else
ImpCastExprToType(rex, lType, CK_BitCast);
}
return ResultTy; return ResultTy;
} }
@ -7053,39 +7057,46 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
&& ((lType->isBlockPointerType() && rType->isPointerType()) && ((lType->isBlockPointerType() && rType->isPointerType())
|| (lType->isPointerType() && rType->isBlockPointerType()))) { || (lType->isPointerType() && rType->isBlockPointerType()))) {
if (!LHSIsNull && !RHSIsNull) { if (!LHSIsNull && !RHSIsNull) {
if (!((rType->isPointerType() && rType->getAs<PointerType>() if (!((rType->isPointerType() && rType->castAs<PointerType>()
->getPointeeType()->isVoidType()) ->getPointeeType()->isVoidType())
|| (lType->isPointerType() && lType->getAs<PointerType>() || (lType->isPointerType() && lType->castAs<PointerType>()
->getPointeeType()->isVoidType()))) ->getPointeeType()->isVoidType())))
Diag(Loc, diag::err_typecheck_comparison_of_distinct_blocks) Diag(Loc, diag::err_typecheck_comparison_of_distinct_blocks)
<< lType << rType << lex->getSourceRange() << rex->getSourceRange(); << lType << rType << lex->getSourceRange() << rex->getSourceRange();
} }
ImpCastExprToType(rex, lType, CK_BitCast); if (LHSIsNull && !RHSIsNull)
ImpCastExprToType(lex, rType, CK_BitCast);
else
ImpCastExprToType(rex, lType, CK_BitCast);
return ResultTy; return ResultTy;
} }
if ((lType->isObjCObjectPointerType() || rType->isObjCObjectPointerType())) { if (lType->isObjCObjectPointerType() || rType->isObjCObjectPointerType()) {
if (lType->isPointerType() || rType->isPointerType()) { const PointerType *LPT = lType->getAs<PointerType>();
const PointerType *LPT = lType->getAs<PointerType>(); const PointerType *RPT = rType->getAs<PointerType>();
const PointerType *RPT = rType->getAs<PointerType>(); if (LPT || RPT) {
bool LPtrToVoid = LPT ? bool LPtrToVoid = LPT ? LPT->getPointeeType()->isVoidType() : false;
Context.getCanonicalType(LPT->getPointeeType())->isVoidType() : false; bool RPtrToVoid = RPT ? RPT->getPointeeType()->isVoidType() : false;
bool RPtrToVoid = RPT ?
Context.getCanonicalType(RPT->getPointeeType())->isVoidType() : false;
if (!LPtrToVoid && !RPtrToVoid && if (!LPtrToVoid && !RPtrToVoid &&
!Context.typesAreCompatible(lType, rType)) { !Context.typesAreCompatible(lType, rType)) {
Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers) Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
<< lType << rType << lex->getSourceRange() << rex->getSourceRange(); << lType << rType << lex->getSourceRange() << rex->getSourceRange();
} }
ImpCastExprToType(rex, lType, CK_BitCast); if (LHSIsNull && !RHSIsNull)
ImpCastExprToType(lex, rType, CK_BitCast);
else
ImpCastExprToType(rex, lType, CK_BitCast);
return ResultTy; return ResultTy;
} }
if (lType->isObjCObjectPointerType() && rType->isObjCObjectPointerType()) { if (lType->isObjCObjectPointerType() && rType->isObjCObjectPointerType()) {
if (!Context.areComparableObjCPointerTypes(lType, rType)) if (!Context.areComparableObjCPointerTypes(lType, rType))
Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers) Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
<< lType << rType << lex->getSourceRange() << rex->getSourceRange(); << lType << rType << lex->getSourceRange() << rex->getSourceRange();
ImpCastExprToType(rex, lType, CK_BitCast); if (LHSIsNull && !RHSIsNull)
ImpCastExprToType(lex, rType, CK_BitCast);
else
ImpCastExprToType(rex, lType, CK_BitCast);
return ResultTy; return ResultTy;
} }
} }