[cfe-commits] r133196 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp test/SemaCXX/null_in_arithmetic_ops.cpp test/SemaCXX/nullptr_in_arithmetic_ops.cpp test/SemaObjCXX/null_objc_pointer.mm

Chad Rosier mcrosier at apple.com
Thu Jun 16 17:32:14 PDT 2011


Hi Richard,
I believe your commit is causing a regression due to excessive warnings.

See: 
http://smooshlab.apple.com:8013/builders/gccTestSuite_clang-x86_64-darwin10-RA__c%2B%2B/builds/854

The specific test case is:
http://www.llvm.org/viewvc/llvm-project/clang-tests/trunk/gcc-4_2-testsuite/src/g%2B%2B.old-deja/g%2B%2B.other/null1.C?view=log

 Thanks,
   Chad


On Jun 16, 2011, at 2:36 PM, Richard Trieu wrote:

> Author: rtrieu
> Date: Thu Jun 16 16:36:56 2011
> New Revision: 133196
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=133196&view=rev
> Log:
> 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;
> 
> 
> Added:
>    cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp
>    cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
>    cfe/trunk/test/SemaObjCXX/null_objc_pointer.mm
> Modified:
>    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>    cfe/trunk/lib/Sema/SemaExpr.cpp
> 
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=133196&r1=133195&r2=133196&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Jun 16 16:36:56 2011
> @@ -2994,6 +2994,8 @@
> def warn_comparison_of_mixed_enum_types : Warning<
>   "comparison of two values with different enumeration types (%0 and %1)">,
>   InGroup<DiagGroup<"enum-compare">>;
> +def warn_null_in_arithmetic_operation : Warning<
> +  "use of NULL in arithmetic operation">;
> 
> def err_invalid_this_use : Error<
>   "invalid use of 'this' outside of a nonstatic member function">;
> 
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=133196&r1=133195&r2=133196&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Jun 16 16:36:56 2011
> @@ -8925,6 +8925,60 @@
>     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());
> 
> Added: 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=133196&view=auto
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp (added)
> +++ cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp Thu Jun 16 16:36:56 2011
> @@ -0,0 +1,70 @@
> +// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s
> +#include <stddef.h>
> +
> +void f() {
> +  int a;
> +  bool b;
> +
> +  a = 0 ? NULL + a : a + NULL; // expected-warning 2{{use of NULL in arithmetic operation}}
> +  a = 0 ? NULL - a : a - NULL; // expected-warning 2{{use of NULL in arithmetic operation}}
> +  a = 0 ? NULL / a : a / NULL; // expected-warning 2{{use of NULL in arithmetic operation}} \
> +                               // expected-warning {{division by zero is undefined}}
> +  a = 0 ? NULL * a : a * NULL; // expected-warning 2{{use of NULL in arithmetic operation}}
> +  a = 0 ? NULL >> a : a >> NULL; // expected-warning 2{{use of NULL in arithmetic operation}}
> +  a = 0 ? NULL << a : a << NULL; // expected-warning 2{{use of NULL in arithmetic operation}}
> +  a = 0 ? NULL % a : a % NULL; // expected-warning 2{{use of NULL in arithmetic operation}} \
> +                                  expected-warning {{remainder by zero is undefined}}
> +  a = 0 ? NULL & a : a & NULL; // expected-warning 2{{use of NULL in arithmetic operation}}
> +  a = 0 ? NULL | a : a | NULL; // expected-warning 2{{use of NULL in arithmetic operation}}
> +  a = 0 ? NULL ^ a : a ^ NULL; // expected-warning 2{{use of NULL in arithmetic operation}}
> +
> +  // Using two NULLs should only give one error instead of two.
> +  a = NULL + NULL; // expected-warning{{use of NULL in arithmetic operation}}
> +  a = NULL - NULL; // expected-warning{{use of NULL in arithmetic operation}}
> +  a = NULL / NULL; // expected-warning{{use of NULL in arithmetic operation}} \
> +                   // expected-warning{{division by zero is undefined}}
> +  a = NULL * NULL; // expected-warning{{use of NULL in arithmetic operation}}
> +  a = NULL >> NULL; // expected-warning{{use of NULL in arithmetic operation}}
> +  a = NULL << NULL; // expected-warning{{use of NULL in arithmetic operation}}
> +  a = NULL % NULL; // expected-warning{{use of NULL in arithmetic operation}} \
> +                   // expected-warning{{remainder by zero is undefined}}
> +  a = NULL & NULL; // expected-warning{{use of NULL in arithmetic operation}}
> +  a = NULL | NULL; // expected-warning{{use of NULL in arithmetic operation}}
> +  a = NULL ^ NULL; // expected-warning{{use of NULL in arithmetic operation}}
> +
> +  a += NULL; // expected-warning{{use of NULL in arithmetic operation}}
> +  a -= NULL; // expected-warning{{use of NULL in arithmetic operation}}
> +  a /= NULL; // expected-warning{{use of NULL in arithmetic operation}} \
> +             // expected-warning{{division by zero is undefined}}
> +  a *= NULL; // expected-warning{{use of NULL in arithmetic operation}}
> +  a >>= NULL; // expected-warning{{use of NULL in arithmetic operation}}
> +  a <<= NULL; // expected-warning{{use of NULL in arithmetic operation}}
> +  a %= NULL; // expected-warning{{use of NULL in arithmetic operation}} \
> +             // expected-warning{{remainder by zero is undefined}}
> +  a &= NULL; // expected-warning{{use of NULL in arithmetic operation}}
> +  a |= NULL; // expected-warning{{use of NULL in arithmetic operation}}
> +  a ^= NULL; // expected-warning{{use of NULL in arithmetic operation}}
> +
> +  b = a < NULL || NULL < a; // expected-warning 2{{use of NULL in arithmetic operation}}
> +  b = a > NULL || NULL > a; // expected-warning 2{{use of NULL in arithmetic operation}}
> +  b = a <= NULL || NULL <= a; // expected-warning 2{{use of NULL in arithmetic operation}}
> +  b = a >= NULL || NULL >= a; // expected-warning 2{{use of NULL in arithmetic operation}}
> +  b = a == NULL || NULL == a; // expected-warning 2{{use of NULL in arithmetic operation}}
> +  b = a != NULL || NULL != a; // expected-warning 2{{use of NULL in arithmetic operation}}
> +
> +  b = &a < NULL || NULL < &a || &a > NULL || NULL > &a;
> +  b = &a <= NULL || NULL <= &a || &a >= NULL || NULL >= &a;
> +  b = &a == NULL || NULL == &a || &a != NULL || NULL != &a;
> +
> +  b = 0 == a;
> +  b = 0 == &a;
> +
> +  b = ((NULL)) != a;  // expected-warning{{use of NULL in arithmetic operation}}
> +
> +  void (^c)();
> +  b = c == NULL || NULL == c || c != NULL || NULL != c;
> +
> +  class X;
> +  void (X::*d) ();
> +  b = d == NULL || NULL == d || d != NULL || NULL != d;
> +}
> 
> Added: 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=133196&view=auto
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp (added)
> +++ cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp Thu Jun 16 16:36:56 2011
> @@ -0,0 +1,65 @@
> +// RUN: %clang_cc1 -fsyntax-only -fblocks -std=c++0x -verify %s
> +
> +void f() {
> +  int a;
> +  bool b;
> +
> +  a = 0 ? nullptr + a : a + nullptr; // expected-error 2{{invalid operands to binary expression}}
> +  a = 0 ? nullptr - a : a - nullptr; // expected-error 2{{invalid operands to binary expression}}
> +  a = 0 ? nullptr / a : a / nullptr; // expected-error 2{{invalid operands to binary expression}}
> +  a = 0 ? nullptr * a : a * nullptr; // expected-error 2{{invalid operands to binary expression}}
> +  a = 0 ? nullptr >> a : a >> nullptr; // expected-error 2{{invalid operands to binary expression}}
> +  a = 0 ? nullptr << a : a << nullptr; // expected-error 2{{invalid operands to binary expression}}
> +  a = 0 ? nullptr % a : a % nullptr; // expected-error 2{{invalid operands to binary expression}}
> +  a = 0 ? nullptr & a : a & nullptr; // expected-error 2{{invalid operands to binary expression}}
> +  a = 0 ? nullptr | a : a | nullptr; // expected-error 2{{invalid operands to binary expression}}
> +  a = 0 ? nullptr ^ a : a ^ nullptr; // expected-error 2{{invalid operands to binary expression}}
> +
> +  // Using two nullptrs should only give one error instead of two.
> +  a = nullptr + nullptr; // expected-error{{invalid operands to binary expression}}
> +  a = nullptr - nullptr; // expected-error{{invalid operands to binary expression}}
> +  a = nullptr / nullptr; // expected-error{{invalid operands to binary expression}}
> +  a = nullptr * nullptr; // expected-error{{invalid operands to binary expression}}
> +  a = nullptr >> nullptr; // expected-error{{invalid operands to binary expression}}
> +  a = nullptr << nullptr; // expected-error{{invalid operands to binary expression}}
> +  a = nullptr % nullptr; // expected-error{{invalid operands to binary expression}}
> +  a = nullptr & nullptr; // expected-error{{invalid operands to binary expression}}
> +  a = nullptr | nullptr; // expected-error{{invalid operands to binary expression}}
> +  a = nullptr ^ nullptr; // expected-error{{invalid operands to binary expression}}
> +
> +  a += nullptr; // expected-error{{invalid operands to binary expression}}
> +  a -= nullptr; // expected-error{{invalid operands to binary expression}}
> +  a /= nullptr; // expected-error{{invalid operands to binary expression}}
> +  a *= nullptr; // expected-error{{invalid operands to binary expression}}
> +  a >>= nullptr; // expected-error{{invalid operands to binary expression}}
> +  a <<= nullptr; // expected-error{{invalid operands to binary expression}}
> +  a %= nullptr; // expected-error{{invalid operands to binary expression}}
> +  a &= nullptr; // expected-error{{invalid operands to binary expression}}
> +  a |= nullptr; // expected-error{{invalid operands to binary expression}}
> +  a ^= nullptr; // expected-error{{invalid operands to binary expression}}
> +
> +  b = a < nullptr || nullptr < a; // expected-error 2{{invalid operands to binary expression}}
> +  b = a > nullptr || nullptr > a; // expected-error 2{{invalid operands to binary expression}}
> +  b = a <= nullptr || nullptr <= a; // expected-error 2{{invalid operands to binary expression}}
> +  b = a >= nullptr || nullptr >= a; // expected-error 2{{invalid operands to binary expression}}
> +  b = a == nullptr || nullptr == a; // expected-error 2{{invalid operands to binary expression}}
> +  b = a != nullptr || nullptr != a; // expected-error 2{{invalid operands to binary expression}}
> +
> +  b = &a < nullptr || nullptr < &a || &a > nullptr || nullptr > &a;
> +  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)) != a;  // expected-error{{invalid operands to binary expression}}
> +
> +  void (^c)();
> +  c = nullptr;
> +  b = c == nullptr || nullptr == c || c != nullptr || nullptr != c;
> +  
> +  class X;
> +  void (X::*d) ();
> +  d = nullptr;
> +  b = d == nullptr || nullptr == d || d != nullptr || nullptr != d;
> +}
> 
> Added: cfe/trunk/test/SemaObjCXX/null_objc_pointer.mm
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/null_objc_pointer.mm?rev=133196&view=auto
> ==============================================================================
> --- cfe/trunk/test/SemaObjCXX/null_objc_pointer.mm (added)
> +++ cfe/trunk/test/SemaObjCXX/null_objc_pointer.mm Thu Jun 16 16:36:56 2011
> @@ -0,0 +1,13 @@
> +// RUN: %clang_cc1 -fsyntax-only -verify %s
> +#define NULL __null
> +
> + at interface X
> + at end
> +
> +void f() {
> +  bool b;
> +  X *d;
> +  b = d < NULL || NULL < d || d > NULL || NULL > d;
> +  b = d <= NULL || NULL <= d || d >= NULL || NULL >= d;
> +  b = d == NULL || NULL == d || d != NULL || NULL != d;
> +}
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




More information about the cfe-commits mailing list