diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 52fa932eee8..b407fb3c137 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -10443,6 +10443,32 @@ static QualType checkArithmeticOrEnumeralCompare(Sema &S, ExprResult &LHS, return S.Context.getLogicalOperationType(); } +void Sema::CheckPtrComparisonWithNullChar(ExprResult &E, ExprResult &NullE) { + if (!NullE.get()->getType()->isAnyPointerType()) + return; + int NullValue = PP.isMacroDefined("NULL") ? 0 : 1; + if (!E.get()->getType()->isAnyPointerType() && + E.get()->isNullPointerConstant(Context, + Expr::NPC_ValueDependentIsNotNull) == + Expr::NPCK_ZeroExpression) { + if (const auto *CL = dyn_cast<CharacterLiteral>(E.get())) { + if (CL->getValue() == 0) + Diag(E.get()->getExprLoc(), diag::warn_pointer_compare) + << NullValue + << FixItHint::CreateReplacement(E.get()->getExprLoc(), + NullValue ? "NULL" : "(void *)0"); + } else if (const auto *CE = dyn_cast<CStyleCastExpr>(E.get())) { + TypeSourceInfo *TI = CE->getTypeInfoAsWritten(); + QualType T = Context.getCanonicalType(TI->getType()).getUnqualifiedType(); + if (T == Context.CharTy) + Diag(E.get()->getExprLoc(), diag::warn_pointer_compare) + << NullValue + << FixItHint::CreateReplacement(E.get()->getExprLoc(), + NullValue ? "NULL" : "(void *)0"); + } + } +} + // C99 6.5.8, C++ [expr.rel] QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, @@ -10476,6 +10502,10 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, } checkArithmeticNull(*this, LHS, RHS, Loc, /*IsCompare=*/true); + if (!getLangOpts().CPlusPlus && BinaryOperator::isEqualityOp(Opc)) { + CheckPtrComparisonWithNullChar(LHS, RHS); + CheckPtrComparisonWithNullChar(RHS, LHS); + } // Handle vector comparisons separately. if (LHS.get()->getType()->isVectorType() || |

