[cfe-commits] r133383 - in /cfe/trunk: include/clang/AST/Type.h lib/AST/Type.cpp lib/Sema/SemaExpr.cpp test/SemaCXX/null_in_arithmetic_ops.cpp test/SemaCXX/nullptr_in_arithmetic_ops.cpp
Chandler Carruth
chandlerc at gmail.com
Sun Jun 19 02:05:14 PDT 2011
Author: chandlerc
Date: Sun Jun 19 04:05:14 2011
New Revision: 133383
URL: http://llvm.org/viewvc/llvm-project?rev=133383&view=rev
Log:
Add test cases for false positives on -Wnull-arithmetic from Richard
Trieu, and fix them by checking for array and function types as well as
pointer types.
I've added a predicate method on Type to bundle together the logic we're
using here: isPointerLikeType(). I'd welcome better names for this
predicate, this is the best I came up with. It's implemented as a switch
to be a touch lighter weight than all the chained isa<...> casts that
would result otherwise.
Modified:
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp
cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=133383&r1=133382&r2=133383&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Sun Jun 19 04:05:14 2011
@@ -1373,6 +1373,7 @@
bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); }
bool isPointerType() const;
bool isAnyPointerType() const; // Any C pointer or ObjC object pointer
+ bool isPointerLikeType() const;
bool isBlockPointerType() const;
bool isVoidPointerType() const;
bool isReferenceType() const;
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=133383&r1=133382&r2=133383&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Sun Jun 19 04:05:14 2011
@@ -289,6 +289,31 @@
}
}
+/// \brief Tests whether the type behaves like a pointer type.
+///
+/// This includes all of the obviously pointer types including block pointers,
+/// member pointers, and ObjC Object pointers. It also includes function and
+/// array types which behave as pointers due to decay.
+///
+/// \returns True for types which act like pointer types.
+bool Type::isPointerLikeType() const {
+ switch (CanonicalType->getTypeClass()) {
+ case Pointer:
+ case BlockPointer:
+ case MemberPointer:
+ case ConstantArray:
+ case IncompleteArray:
+ case VariableArray:
+ case DependentSizedArray:
+ case FunctionProto:
+ case FunctionNoProto:
+ case ObjCObjectPointer:
+ return true;
+ default:
+ return false;
+ }
+}
+
bool Type::isClassType() const {
if (const RecordType *RT = getAs<RecordType>())
return RT->getDecl()->isClass();
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=133383&r1=133382&r2=133383&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sun Jun 19 04:05:14 2011
@@ -8953,37 +8953,20 @@
Opc == BO_AndAssign || Opc == BO_OrAssign || Opc == BO_XorAssign) {
// These are the operations that would not make sense with a null pointer
// no matter what the other expression is.
- if (LeftNull && RightNull) {
- Diag(OpLoc, diag::warn_null_in_arithmetic_operation)
- << lhs.get()->getSourceRange() << rhs.get()->getSourceRange();
- } else if (LeftNull) {
- Diag(OpLoc, diag::warn_null_in_arithmetic_operation)
- << lhs.get()->getSourceRange();
- } else if (RightNull) {
- Diag(OpLoc, diag::warn_null_in_arithmetic_operation)
- << rhs.get()->getSourceRange();
- }
+ Diag(OpLoc, diag::warn_null_in_arithmetic_operation)
+ << (LeftNull ? lhs.get()->getSourceRange() : SourceRange())
+ << (RightNull ? rhs.get()->getSourceRange() : SourceRange());
} else if (Opc == BO_LE || Opc == BO_LT || Opc == BO_GE || Opc == BO_GT ||
Opc == BO_EQ || Opc == BO_NE) {
// These are the operations that would not make sense with a null pointer
// if the other expression the other expression is not a pointer.
QualType LeftType = lhs.get()->getType();
QualType RightType = rhs.get()->getType();
- bool LeftPointer = LeftType->isPointerType() ||
- LeftType->isBlockPointerType() ||
- LeftType->isMemberPointerType() ||
- LeftType->isObjCObjectPointerType();
- bool RightPointer = RightType->isPointerType() ||
- RightType->isBlockPointerType() ||
- RightType->isMemberPointerType() ||
- RightType->isObjCObjectPointerType();
- if ((LeftNull != RightNull) && !LeftPointer && !RightPointer) {
- if (LeftNull)
- Diag(OpLoc, diag::warn_null_in_arithmetic_operation)
- << lhs.get()->getSourceRange();
- if (RightNull)
- Diag(OpLoc, diag::warn_null_in_arithmetic_operation)
- << rhs.get()->getSourceRange();
+ if (LeftNull != RightNull &&
+ !LeftType->isPointerLikeType() && !RightType->isPointerLikeType()) {
+ Diag(OpLoc, diag::warn_null_in_arithmetic_operation)
+ << (LeftNull ? lhs.get()->getSourceRange()
+ : rhs.get()->getSourceRange());
}
}
}
Modified: cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp?rev=133383&r1=133382&r2=133383&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp (original)
+++ cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp Sun Jun 19 04:05:14 2011
@@ -59,6 +59,10 @@
b = 0 == a;
b = 0 == &a;
+ b = NULL < NULL || NULL > NULL;
+ b = NULL <= NULL || NULL >= NULL;
+ b = NULL == NULL || NULL != NULL;
+
b = ((NULL)) != a; // expected-warning{{use of NULL in arithmetic operation}}
void (^c)();
@@ -67,4 +71,11 @@
class X;
void (X::*d) ();
b = d == NULL || NULL == d || d != NULL || NULL != d;
+
+ extern void e();
+ b = e == NULL || NULL == e || e != NULL || NULL != e;
+
+ int f[2];
+ b = f == NULL || NULL == f || f != NULL || NULL != f;
+ b = "f" == NULL || NULL == "f" || "f" != NULL || NULL != "f";
}
Modified: cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp?rev=133383&r1=133382&r2=133383&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp (original)
+++ cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp Sun Jun 19 04:05:14 2011
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -fblocks -std=c++0x -verify %s
-void f() {
+void foo() {
int a;
bool b;
@@ -49,8 +49,9 @@
b = &a <= nullptr || nullptr <= &a || &a >= nullptr || nullptr >= &a;
b = &a == nullptr || nullptr == &a || &a != nullptr || nullptr != &a;
- b = 0 == a;
- b = 0 == &a;
+ b = nullptr < nullptr || nullptr > nullptr;
+ b = nullptr <= nullptr || nullptr >= nullptr;
+ b = nullptr == nullptr || nullptr != nullptr;
b = ((nullptr)) != a; // expected-error{{invalid operands to binary expression}}
@@ -62,4 +63,11 @@
void (X::*d) ();
d = nullptr;
b = d == nullptr || nullptr == d || d != nullptr || nullptr != d;
+
+ extern void e();
+ b = e == nullptr || nullptr == e || e != nullptr || nullptr != e;
+
+ int f[2];
+ b = f == nullptr || nullptr == f || f != nullptr || nullptr != f;
+ b = "f" == nullptr || nullptr == "f" || "f" != nullptr || nullptr != "f";
}
More information about the cfe-commits
mailing list