summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/test/clang-tidy/modernize-use-nullptr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/test/clang-tidy/modernize-use-nullptr.cpp')
-rw-r--r--clang-tools-extra/test/clang-tidy/modernize-use-nullptr.cpp178
1 files changed, 178 insertions, 0 deletions
diff --git a/clang-tools-extra/test/clang-tidy/modernize-use-nullptr.cpp b/clang-tools-extra/test/clang-tidy/modernize-use-nullptr.cpp
new file mode 100644
index 00000000000..df8f30adf30
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/modernize-use-nullptr.cpp
@@ -0,0 +1,178 @@
+// RUN: $(dirname %s)/check_clang_tidy.sh %s modernize-use-nullptr %t \
+// RUN: -config="{CheckOptions: [{key: modernize-use-nullptr.UserNullMacros, value: 'MY_NULL'}]}" \
+// RUN: -- -std=c++11
+// REQUIRES: shell
+
+#define NULL 0
+
+namespace std {
+
+typedef decltype(nullptr) nullptr_t;
+
+} // namespace std
+
+// Just to make sure make_null() could have side effects.
+void external();
+
+std::nullptr_t make_null() {
+ external();
+ return nullptr;
+}
+
+void func() {
+ void *CallTest = make_null();
+
+ int var = 1;
+ void *CommaTest = (var+=2, make_null());
+
+ int *CastTest = static_cast<int*>(make_null());
+}
+
+void dummy(int*) {}
+void side_effect() {}
+
+#define MACRO_EXPANSION_HAS_NULL \
+ void foo() { \
+ dummy(0); \
+ dummy(NULL); \
+ side_effect(); \
+ }
+
+MACRO_EXPANSION_HAS_NULL;
+#undef MACRO_EXPANSION_HAS_NULL
+
+
+void test_macro_expansion1() {
+#define MACRO_EXPANSION_HAS_NULL \
+ dummy(NULL); \
+ side_effect();
+
+ MACRO_EXPANSION_HAS_NULL;
+
+#undef MACRO_EXPANSION_HAS_NULL
+}
+
+// Test macro expansion with cast sequence, PR15572.
+void test_macro_expansion2() {
+#define MACRO_EXPANSION_HAS_NULL \
+ dummy((int*)0); \
+ side_effect();
+
+ MACRO_EXPANSION_HAS_NULL;
+
+#undef MACRO_EXPANSION_HAS_NULL
+}
+
+void test_macro_expansion3() {
+#define MACRO_EXPANSION_HAS_NULL \
+ dummy(NULL); \
+ side_effect();
+
+#define OUTER_MACRO \
+ MACRO_EXPANSION_HAS_NULL; \
+ side_effect();
+
+ OUTER_MACRO;
+
+#undef OUTER_MACRO
+#undef MACRO_EXPANSION_HAS_NULL
+}
+
+void test_macro_expansion4() {
+#define MY_NULL NULL
+ int *p = MY_NULL;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr [modernize-use-nullptr]
+ // CHECK-FIXES: int *p = nullptr;
+#undef MY_NULL
+}
+
+#define IS_EQ(x, y) if (x != y) return;
+void test_macro_args() {
+ int i = 0;
+ int *Ptr;
+
+ IS_EQ(static_cast<int*>(0), Ptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use nullptr
+ // CHECK-FIXES: IS_EQ(static_cast<int*>(nullptr), Ptr);
+
+ IS_EQ(0, Ptr); // literal
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
+ // CHECK-FIXES: IS_EQ(nullptr, Ptr);
+
+ IS_EQ(NULL, Ptr); // macro
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
+ // CHECK-FIXES: IS_EQ(nullptr, Ptr);
+
+ // These are ok since the null literal is not spelled within a macro.
+#define myassert(x) if (!(x)) return;
+ myassert(0 == Ptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr
+ // CHECK-FIXES: myassert(nullptr == Ptr);
+
+ myassert(NULL == Ptr);
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr
+ // CHECK-FIXES: myassert(nullptr == Ptr);
+
+ // These are bad as the null literal is buried in a macro.
+#define BLAH(X) myassert(0 == (X));
+#define BLAH2(X) myassert(NULL == (X));
+ BLAH(Ptr);
+ BLAH2(Ptr);
+
+ // Same as above but testing extra macro expansion.
+#define EXPECT_NULL(X) IS_EQ(0, X);
+#define EXPECT_NULL2(X) IS_EQ(NULL, X);
+ EXPECT_NULL(Ptr);
+ EXPECT_NULL2(Ptr);
+
+ // Almost the same as above but now null literal is not in a macro so ok
+ // to transform.
+#define EQUALS_PTR(X) IS_EQ(X, Ptr);
+ EQUALS_PTR(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use nullptr
+ // CHECK-FIXES: EQUALS_PTR(nullptr);
+ EQUALS_PTR(NULL);
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use nullptr
+ // CHECK-FIXES: EQUALS_PTR(nullptr);
+
+ // Same as above but testing extra macro expansion.
+#define EQUALS_PTR_I(X) EQUALS_PTR(X)
+ EQUALS_PTR_I(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr
+ // CHECK-FIXES: EQUALS_PTR_I(nullptr);
+ EQUALS_PTR_I(NULL);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr
+ // CHECK-FIXES: EQUALS_PTR_I(nullptr);
+
+ // Ok since null literal not within macro. However, now testing macro
+ // used as arg to another macro.
+#define decorate(EXPR) side_effect(); EXPR;
+ decorate(IS_EQ(NULL, Ptr));
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr
+ // CHECK-FIXES: decorate(IS_EQ(nullptr, Ptr));
+ decorate(IS_EQ(0, Ptr));
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr
+ // CHECK-FIXES: decorate(IS_EQ(nullptr, Ptr));
+
+ // This macro causes a NullToPointer cast to happen where 0 is assigned to z
+ // but the 0 literal cannot be replaced because it is also used as an
+ // integer in the comparison.
+#define INT_AND_PTR_USE(X) do { int *z = X; if (X == 4) break; } while(false)
+ INT_AND_PTR_USE(0);
+
+ // Both uses of X in this case result in NullToPointer casts so replacement
+ // is possible.
+#define PTR_AND_PTR_USE(X) do { int *z = X; if (X != z) break; } while(false)
+ PTR_AND_PTR_USE(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr
+ // CHECK-FIXES: PTR_AND_PTR_USE(nullptr);
+ PTR_AND_PTR_USE(NULL);
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr
+ // CHECK-FIXES: PTR_AND_PTR_USE(nullptr);
+
+#define OPTIONAL_CODE(...) __VA_ARGS__
+#define NOT_NULL dummy(0)
+#define CALL(X) X
+ OPTIONAL_CODE(NOT_NULL);
+ CALL(NOT_NULL);
+}
OpenPOWER on IntegriCloud