aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorRichard Trieu <rtrieu@google.com>2011-06-16 21:36:56 +0000
committerRichard Trieu <rtrieu@google.com>2011-06-16 21:36:56 +0000
commit3e95ba94fd34c5f6420c57d7732f601875074681 (patch)
treef9d91882f472c5ab6fc330c73d0819f5e98ed7f9 /lib/Sema/SemaExpr.cpp
parenta92d7e7a55a35b28437103130904a6401bf35408 (diff)
Add a new warning when a NULL constant is used in arithmetic operations. The warning will fire on cases such as:
int x = 1 + NULL; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133196 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r--lib/Sema/SemaExpr.cpp54
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 76612cd6d8..2c988d15e3 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -8925,6 +8925,60 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
rhs = move(resolvedRHS);
}
+ bool LeftNull = Expr::NPCK_GNUNull ==
+ lhs.get()->isNullPointerConstant(Context,
+ Expr::NPC_ValueDependentIsNotNull);
+ bool RightNull = Expr::NPCK_GNUNull ==
+ rhs.get()->isNullPointerConstant(Context,
+ Expr::NPC_ValueDependentIsNotNull);
+
+ // Detect when a NULL constant is used improperly in an expression. These
+ // are mainly cases where the null pointer is used as an integer instead
+ // of a pointer.
+ if (LeftNull || RightNull) {
+ if (Opc == BO_Mul || Opc == BO_Div || Opc == BO_Rem || Opc == BO_Add ||
+ Opc == BO_Sub || Opc == BO_Shl || Opc == BO_Shr || Opc == BO_And ||
+ Opc == BO_Xor || Opc == BO_Or || Opc == BO_MulAssign ||
+ Opc == BO_DivAssign || Opc == BO_AddAssign || Opc == BO_SubAssign ||
+ Opc == BO_RemAssign || Opc == BO_ShlAssign || Opc == BO_ShrAssign ||
+ 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();
+ }
+ } 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();
+ }
+ }
+ }
+
switch (Opc) {
case BO_Assign:
ResultTy = CheckAssignmentOperands(lhs.get(), rhs, OpLoc, QualType());