brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.9 KiB · 27a9629 Raw
332 lines · cpp
1// RUN: %check_clang_tidy %s modernize-use-nullptr %t -- \2// RUN:   -config="{CheckOptions: {modernize-use-nullptr.NullMacros: 'MY_NULL,NULL'}}"3 4#define NULL 05 6namespace std {7 8typedef decltype(nullptr) nullptr_t;9 10} // namespace std11 12// Just to make sure make_null() could have side effects.13void external();14 15std::nullptr_t make_null() {16  external();17  return nullptr;18}19 20void func() {21  void *CallTest = make_null();22 23  int var = 1;24  void *CommaTest = (var+=2, make_null());25 26  int *CastTest = static_cast<int*>(make_null());27}28 29void dummy(int*) {}30void side_effect() {}31 32#define MACRO_EXPANSION_HAS_NULL \33  void foo() { \34    dummy(0); \35    dummy(NULL); \36    side_effect(); \37  }38 39MACRO_EXPANSION_HAS_NULL;40#undef MACRO_EXPANSION_HAS_NULL41 42 43void test_macro_expansion1() {44#define MACRO_EXPANSION_HAS_NULL \45  dummy(NULL); \46  side_effect();47 48  MACRO_EXPANSION_HAS_NULL;49 50#undef MACRO_EXPANSION_HAS_NULL51}52 53// Test macro expansion with cast sequence, PR15572.54void test_macro_expansion2() {55#define MACRO_EXPANSION_HAS_NULL \56  dummy((int*)0); \57  side_effect();58 59  MACRO_EXPANSION_HAS_NULL;60 61#undef MACRO_EXPANSION_HAS_NULL62}63 64void test_macro_expansion3() {65#define MACRO_EXPANSION_HAS_NULL \66  dummy(NULL); \67  side_effect();68 69#define OUTER_MACRO \70  MACRO_EXPANSION_HAS_NULL; \71  side_effect();72 73  OUTER_MACRO;74 75#undef OUTER_MACRO76#undef MACRO_EXPANSION_HAS_NULL77}78 79void test_macro_expansion4() {80#define MY_NULL NULL81  int *p = MY_NULL;82  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr [modernize-use-nullptr]83  // CHECK-FIXES: int *p = nullptr;84#undef MY_NULL85}86 87template <typename T> struct pear {88  // If you say __null (or NULL), we assume that T will always be a pointer89  // type, so we suggest replacing it with nullptr. (We only check __null here,90  // because in this test NULL is defined as 0, but real library implementations91  // it is often defined as __null and the check will catch it.)92  void f() { x = __null; }93  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr [modernize-use-nullptr]94  // CHECK-FIXES: void f() { x = nullptr; }95 96  // But if you say 0, we allow the possibility that T can be used with integral97  // and pointer types, and "0" is an acceptable initializer (even if "{}" might98  // be even better).99  void g() { y = 0; }100  // CHECK-MESSAGES-NOT: :[[@LINE-1]] warning: use nullptr101 102  T x;103  T y;104};105void test_templated() {106  pear<int*> p;107  p.f();108  p.g();109  dummy(p.x);110}111 112#define IS_EQ(x, y) if (x != y) return;113void test_macro_args() {114  int i = 0;115  int *Ptr;116 117  IS_EQ(static_cast<int*>(0), Ptr);118  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use nullptr119  // CHECK-FIXES: IS_EQ(static_cast<int*>(nullptr), Ptr);120 121  // literal122  IS_EQ(0, Ptr);123  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr124  // CHECK-FIXES: IS_EQ(nullptr, Ptr);125 126  // macro127  IS_EQ(NULL, Ptr);128  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr129  // CHECK-FIXES: IS_EQ(nullptr, Ptr);130 131  // These are ok since the null literal is not spelled within a macro.132#define myassert(x) if (!(x)) return;133  myassert(0 == Ptr);134  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr135  // CHECK-FIXES: myassert(nullptr == Ptr);136 137  myassert(NULL == Ptr);138  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr139  // CHECK-FIXES: myassert(nullptr == Ptr);140 141  // These are bad as the null literal is buried in a macro.142#define BLAH(X) myassert(0 == (X));143#define BLAH2(X) myassert(NULL == (X));144  BLAH(Ptr);145  BLAH2(Ptr);146 147  // Same as above but testing extra macro expansion.148#define EXPECT_NULL(X) IS_EQ(0, X);149#define EXPECT_NULL2(X) IS_EQ(NULL, X);150  EXPECT_NULL(Ptr);151  EXPECT_NULL2(Ptr);152 153  // Almost the same as above but now null literal is not in a macro so ok154  // to transform.155#define EQUALS_PTR(X) IS_EQ(X, Ptr);156  EQUALS_PTR(0);157  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use nullptr158  // CHECK-FIXES: EQUALS_PTR(nullptr);159  EQUALS_PTR(NULL);160  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use nullptr161  // CHECK-FIXES: EQUALS_PTR(nullptr);162 163  // Same as above but testing extra macro expansion.164#define EQUALS_PTR_I(X) EQUALS_PTR(X)165  EQUALS_PTR_I(0);166  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr167  // CHECK-FIXES: EQUALS_PTR_I(nullptr);168  EQUALS_PTR_I(NULL);169  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr170  // CHECK-FIXES: EQUALS_PTR_I(nullptr);171 172  // Ok since null literal not within macro. However, now testing macro173  // used as arg to another macro.174#define decorate(EXPR) side_effect(); EXPR;175  decorate(IS_EQ(NULL, Ptr));176  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr177  // CHECK-FIXES: decorate(IS_EQ(nullptr, Ptr));178  decorate(IS_EQ(0, Ptr));179  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr180  // CHECK-FIXES: decorate(IS_EQ(nullptr, Ptr));181 182  // This macro causes a NullToPointer cast to happen where 0 is assigned to z183  // but the 0 literal cannot be replaced because it is also used as an184  // integer in the comparison.185#define INT_AND_PTR_USE(X) do { int *z = X; if (X == 4) break; } while(false)186  INT_AND_PTR_USE(0);187 188  // Both uses of X in this case result in NullToPointer casts so replacement189  // is possible.190#define PTR_AND_PTR_USE(X) do { int *z = X; if (X != z) break; } while(false)191  PTR_AND_PTR_USE(0);192  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr193  // CHECK-FIXES: PTR_AND_PTR_USE(nullptr);194  PTR_AND_PTR_USE(NULL);195  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr196  // CHECK-FIXES: PTR_AND_PTR_USE(nullptr);197 198#define OPTIONAL_CODE(...) __VA_ARGS__199#define NOT_NULL dummy(0)200#define CALL(X) X201  OPTIONAL_CODE(NOT_NULL);202  CALL(NOT_NULL);203 204#define ENTRY(X) {X}205  struct A {206    int *Ptr;207  } a[2] = {ENTRY(0), {0}};208  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr209  // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: use nullptr210  // CHECK-FIXES: } a[2] = {ENTRY(nullptr), {nullptr}};211#undef ENTRY212 213#define assert1(expr) (expr) ? 0 : 1214#define assert2 assert1215  int *p;216  assert2(p == 0);217  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr218  // CHECK-FIXES: assert2(p == nullptr);219  assert2(p == NULL);220  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr221  // CHECK-FIXES: assert2(p == nullptr);222#undef assert2223#undef assert1224 225#define ASSERT_EQ(a, b) a == b226#define ASSERT_NULL(x) ASSERT_EQ(static_cast<void *>(NULL), x)227  int *pp;228  ASSERT_NULL(pp);229  ASSERT_NULL(NULL);230  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use nullptr231  // CHECK-FIXES: ASSERT_NULL(nullptr);232#undef ASSERT_NULL233#undef ASSERT_EQ234}235 236// One of the ancestor of the cast is a NestedNameSpecifierLoc.237class NoDef;238char function(NoDef *p);239#define F(x) (sizeof(function(x)) == 1)240template<class T, T t>241class C {};242C<bool, F(0)> c;243// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use nullptr244// CHECK-FIXES: C<bool, F(nullptr)> c;245#undef F246 247// Test default argument expression.248struct D {249  explicit D(void *t, int *c = NULL) {}250  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use nullptr251  // CHECK-FIXES: explicit D(void *t, int *c = nullptr) {}252};253 254void test_default_argument() {255  D(nullptr);256}257 258// Test on two neighbour CXXDefaultArgExprs nodes.259typedef unsigned long long uint64;260struct ZZ {261  explicit ZZ(uint64, const uint64* = NULL) {}262// CHECK-MESSAGES: :[[@LINE-1]]:39: warning: use nullptr263// CHECK-FIXES: explicit ZZ(uint64, const uint64* = nullptr) {}264  operator bool()  { return true; }265};266 267uint64 Hash(uint64 seed = 0) { return 0; }268 269void f() {270  bool a;271  a = ZZ(Hash());272}273 274// Test on ignoring substituted template types.275template<typename T>276class TemplateClass {277 public:278  explicit TemplateClass(int a, T default_value = 0) {}279 280  void h(T *default_value = 0) {}281 282  void f(int* p = 0) {}283// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr284// CHECK-FIXES: void f(int* p = nullptr) {}285};286 287void IgnoreSubstTemplateType() {288  TemplateClass<int*> a(1);289}290 291// Test on casting nullptr.292struct G {293  explicit G(bool, const char * = NULL) {}294  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use nullptr295  // CHECK-FIXES: explicit G(bool, const char * = nullptr) {}296};297bool g(const char*);298void test_cast_nullptr() {299  G(g(nullptr));300  G(g((nullptr)));301  G(g(static_cast<char*>(nullptr)));302  G(g(static_cast<const char*>(nullptr)));303}304 305// Test on recognizing multiple NULLs.306class H {307public:308  H(bool);309};310 311#define T(expression) H(expression);312bool h(int *, int *, int * = nullptr);313void test_multiple_nulls() {314  T(h(NULL, NULL));315// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use nullptr316// CHECK-MESSAGES: :[[@LINE-2]]:13: warning: use nullptr317// CHECK-FIXES: T(h(nullptr, nullptr));318  T(h(NULL, nullptr));319// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use nullptr320// CHECK-FIXES: T(h(nullptr, nullptr));321  T(h(nullptr, NULL));322// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr323// CHECK-FIXES: T(h(nullptr, nullptr));324  T(h(nullptr, nullptr));325  T(h(NULL, NULL, NULL));326// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use nullptr327// CHECK-MESSAGES: :[[@LINE-2]]:13: warning: use nullptr328// CHECK-MESSAGES: :[[@LINE-3]]:19: warning: use nullptr329// CHECK-FIXES: T(h(nullptr, nullptr, nullptr));330}331#undef T332