Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3287,6 +3287,9 @@ def warn_non_literal_null_pointer : Warning< "expression which evaluates to zero treated as a null pointer constant of " "type %0">, InGroup; +def warn_pointer_compare : Warning< + "comparison between NULL and null character">, + InGroup>, DefaultIgnore; def warn_impcast_null_pointer_to_integer : Warning< "implicit conversion of %select{NULL|nullptr}0 constant to %1">, InGroup; Index: clang/include/clang/Sema/Sema.h =================================================================== --- clang/include/clang/Sema/Sema.h +++ clang/include/clang/Sema/Sema.h @@ -9991,6 +9991,7 @@ QualType CheckShiftOperands( // C99 6.5.7 ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, BinaryOperatorKind Opc, bool IsCompAssign = false); + void checkNullCharToNullptr(ExprResult &E); // helper for CheckCompareOperand QualType CheckCompareOperands( // C99 6.5.8/9 ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, BinaryOperatorKind Opc); Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -10433,6 +10433,19 @@ return S.Context.getLogicalOperationType(); } +// Purely helper function for CheckCompareOperand. +void Sema::checkNullCharToNullptr(ExprResult &E) { + if (!E.get()->getType()->isAnyPointerType() && + E.get()->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull) == + Expr::NPCK_ZeroExpression) { + if (isa(E.get())) { + const CharacterLiteral *RCL = dyn_cast(E.get()); + if (RCL->getValue() == '\0') + Diag(E.get()->getExprLoc(), diag::warn_pointer_compare); + } + } +} + // C99 6.5.8, C++ [expr.rel] QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, @@ -10466,6 +10479,8 @@ } checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/true); + checkNullCharToNullptr(LHS); + checkNullCharToNullptr(RHS); // Handle vector comparisons separately. if (LHS.get()->getType()->isVectorType() || Index: clang/test/Sema/warn-nullchar-nullptr.c =================================================================== --- /dev/null +++ clang/test/Sema/warn-nullchar-nullptr.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wpointer-compare %s +// RUN: %clang_cc1 -fsyntax-only -verify -DSILENCE -Wall %s + +#ifdef SILENCE + // expected-no-diagnostics +#endif + +int test1(int *a) { + return a == '\0'; +#ifndef SILENCE + // expected-warning@-2 {{comparison between NULL and null character}} +#endif +} + +int test2(int *a) { + return '\0' == a; +#ifndef SILENCE + // expected-warning@-2 {{comparison between NULL and null character}} +#endif +}