aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-08-26 01:10:14 +0000
committerChris Lattner <sabre@nondot.org>2007-08-26 01:10:14 +0000
commitd28f815705497f23c2747d61b7834f2d7ea78283 (patch)
tree0f7abd330add317063eb13aca38a3fcb3611f0a6
parent9c62c1d6282ca62200c3887a6837e4eedda53a0f (diff)
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
-rw-r--r--Sema/SemaExpr.cpp34
-rw-r--r--test/Sema/compare.c8
2 files changed, 28 insertions, 14 deletions
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;
+}
+