From: Chris Lattner Date: Sun, 26 Aug 2007 01:10:14 +0000 (+0000) Subject: Cases like this: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d28f815705497f23c2747d61b7834f2d7ea78283;p=clang Cases like this: char *C; C != ((void*)0); Should not warn about incompatible pointer types. Also, make sure to insert an implicit conversion even if the operand is null. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41408 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index 7666ad0474..e26f5c1f3d 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -1068,33 +1068,35 @@ inline QualType Sema::CheckRelationalOperands( // C99 6.5.8 if (lType->isRealType() && rType->isRealType()) return Context.IntTy; + bool LHSIsNull = lex->isNullPointerConstant(Context); + bool RHSIsNull = rex->isNullPointerConstant(Context); + // All of the following pointer related warnings are GCC extensions. One // day, we can consider making them errors (when -pedantic-errors is enabled). if (lType->isPointerType() && rType->isPointerType()) { - if (!Type::pointerTypesAreCompatible(lType, rType)) { + if (!LHSIsNull && !RHSIsNull && + !Type::pointerTypesAreCompatible(lType, rType)) { Diag(loc, diag::ext_typecheck_comparison_of_distinct_pointers, lType.getAsString(), rType.getAsString(), lex->getSourceRange(), rex->getSourceRange()); - promoteExprToType(rex, lType); // promote the pointer to pointer } + promoteExprToType(rex, lType); // promote the pointer to pointer return Context.IntTy; } if (lType->isPointerType() && rType->isIntegerType()) { - if (!rex->isNullPointerConstant(Context)) { + if (!RHSIsNull) Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer, lType.getAsString(), rType.getAsString(), lex->getSourceRange(), rex->getSourceRange()); - promoteExprToType(rex, lType); // promote the integer to pointer - } + promoteExprToType(rex, lType); // promote the integer to pointer return Context.IntTy; } if (lType->isIntegerType() && rType->isPointerType()) { - if (!lex->isNullPointerConstant(Context)) { + if (!LHSIsNull) Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer, lType.getAsString(), rType.getAsString(), lex->getSourceRange(), rex->getSourceRange()); - promoteExprToType(lex, rType); // promote the integer to pointer - } + promoteExprToType(lex, rType); // promote the integer to pointer return Context.IntTy; } InvalidOperands(loc, lex, rex); @@ -1117,33 +1119,37 @@ inline QualType Sema::CheckEqualityOperands( // C99 6.5.9 if (lType->isArithmeticType() && rType->isArithmeticType()) return Context.IntTy; + bool LHSIsNull = lex->isNullPointerConstant(Context); + bool RHSIsNull = rex->isNullPointerConstant(Context); + // All of the following pointer related warnings are GCC extensions. One // day, we can consider making them errors (when -pedantic-errors is enabled). if (lType->isPointerType() && rType->isPointerType()) { - if (!Type::pointerTypesAreCompatible(lType, rType)) { + if (!LHSIsNull && !RHSIsNull && + !Type::pointerTypesAreCompatible(lType, rType)) { Diag(loc, diag::ext_typecheck_comparison_of_distinct_pointers, lType.getAsString(), rType.getAsString(), lex->getSourceRange(), rex->getSourceRange()); - promoteExprToType(rex, lType); // promote the pointer to pointer } + promoteExprToType(rex, lType); // promote the pointer to pointer return Context.IntTy; } if (lType->isPointerType() && rType->isIntegerType()) { - if (!rex->isNullPointerConstant(Context)) { + if (!RHSIsNull) { Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer, lType.getAsString(), rType.getAsString(), lex->getSourceRange(), rex->getSourceRange()); - promoteExprToType(rex, lType); // promote the integer to pointer } + promoteExprToType(rex, lType); // promote the integer to pointer return Context.IntTy; } if (lType->isIntegerType() && rType->isPointerType()) { - if (!lex->isNullPointerConstant(Context)) { + if (!LHSIsNull) { Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer, lType.getAsString(), rType.getAsString(), lex->getSourceRange(), rex->getSourceRange()); - promoteExprToType(lex, rType); // promote the integer to pointer } + promoteExprToType(lex, rType); // promote the integer to pointer return Context.IntTy; } InvalidOperands(loc, lex, rex); diff --git a/test/Sema/compare.c b/test/Sema/compare.c new file mode 100644 index 0000000000..0aeeb30d73 --- /dev/null +++ b/test/Sema/compare.c @@ -0,0 +1,8 @@ +// RUN: clang -parse-ast-check %s + +int test(char *C) { // nothing here should warn. + return C != ((void*)0); + return C != (void*)0; + return C != 0; +} +