diff options
author | Edwin Vane <edwin.vane@intel.com> | 2013-01-22 18:31:49 +0000 |
---|---|---|
committer | Edwin Vane <edwin.vane@intel.com> | 2013-01-22 18:31:49 +0000 |
commit | e93d6aec4dee01889ecdf6b8f2fdb14fd33cfa1d (patch) | |
tree | cfb2564db4318f37240599c46ecace31824e0d4d /test | |
parent | ea1c746944afb7b0aefa0094de8fc8bc7862c085 (diff) |
Add use-nullptr transform to cpp11-migrate
This transform converts the usage of null pointer constants (e.g. NULL, 0,
etc.) in legacy C++ code and converts them to use the new C++11 nullptr
keyword.
- Added use-nullptr transform.
- Added C++11 support to the final syntax check. Used ArgumentAdjuster class to
add -std=c++11 option to the command line options.
- Added tests for use-nullptr transform.
- Added tests that exercises both loop-convert and use-nullptr in the source
file.
TODO: There's a known bug when using both -loop-convert and -use-nullptr at the
same time.
Author: Tareq A Siraj <tareq.a.siraj@intel.com>
Reviewers: klimek, gribozavr
git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@173178 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/cpp11-migrate/Combined/combined.cpp | 47 | ||||
-rw-r--r-- | test/cpp11-migrate/UseNullptr/Inputs/basic.h | 2 | ||||
-rw-r--r-- | test/cpp11-migrate/UseNullptr/basic.cpp | 181 | ||||
-rw-r--r-- | test/cpp11-migrate/UseNullptr/basic_failing.cpp | 28 |
4 files changed, 258 insertions, 0 deletions
diff --git a/test/cpp11-migrate/Combined/combined.cpp b/test/cpp11-migrate/Combined/combined.cpp new file mode 100644 index 00000000..4267d2ed --- /dev/null +++ b/test/cpp11-migrate/Combined/combined.cpp @@ -0,0 +1,47 @@ +// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp +// RUN: grep -Ev "// *[A-Z-]+:" %s > %t_risky.cpp +// RUN: cpp11-migrate -loop-convert -use-nullptr %t.cpp -- +// RUN: FileCheck -input-file=%t.cpp %s +// RUN: cpp11-migrate -loop-convert -use-nullptr -risk=risky %t_risky.cpp -- +// RUN: FileCheck -check-prefix=RISKY -input-file=%t_risky.cpp %s +// REQUIRES: shell +// XFAIL: * + +#define NULL 0 + +struct T { + struct iterator { + int *& operator*(); + const int *& operator*() const; + iterator & operator++(); + bool operator!=(const iterator &other); + void insert(int *); + int *x; + }; + + iterator begin(); + iterator end(); +}; + +void test_loopconvert_and_nullptr_iterator() { + T t; + + for (T::iterator it = t.begin(); it != t.end(); ++it) { + *it = NULL; + } + + // CHECK: for ({{[a-zA-Z_ ]+&? ?}}[[VAR:[a-z_]+]] : t) + // CHECK-NEXT: [[VAR]] = nullptr; +} + +void test_loopconvert_and_nullptr_risky() { + const int N = 10; + int *(*pArr)[N]; + + for (int i = 0; i < N; ++i) { + (*pArr)[i] = NULL; + } + + // RISKY: for (auto & [[VAR:[a-z_]+]] : *pArr) + // RISKY-NEXT: [[VAR:[a-z_]+]] = nullptr; +} diff --git a/test/cpp11-migrate/UseNullptr/Inputs/basic.h b/test/cpp11-migrate/UseNullptr/Inputs/basic.h new file mode 100644 index 00000000..68c5a032 --- /dev/null +++ b/test/cpp11-migrate/UseNullptr/Inputs/basic.h @@ -0,0 +1,2 @@ +int *global_p = 0; +// CHECK: int *global_p = 0; diff --git a/test/cpp11-migrate/UseNullptr/basic.cpp b/test/cpp11-migrate/UseNullptr/basic.cpp new file mode 100644 index 00000000..8a6469c4 --- /dev/null +++ b/test/cpp11-migrate/UseNullptr/basic.cpp @@ -0,0 +1,181 @@ +// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp +// RUN: grep -Ev "// *[A-Z-]+:" %S/Inputs/basic.h > %T/basic.h +// RUN: cpp11-migrate -use-nullptr %t.cpp -- -I %S +// RUN: FileCheck -input-file=%t.cpp %s +// RUN: FileCheck -input-file=%T/basic.h %S/Inputs/basic.h +// REQUIRES: shell + +#include "Inputs/basic.h" + +const unsigned int g_null = 0; +#define NULL 0 + +void test_assignment() { + int *p1 = 0; + // CHECK: int *p1 = nullptr; + p1 = 0; + // CHECK: p1 = nullptr; + + int *p2 = NULL; + // CHECK: int *p2 = nullptr; + + p2 = p1; + // CHECK: p2 = p1; + + const int null = 0; + int *p3 = null; + // CHECK: int *p3 = nullptr; + + p3 = NULL; + // CHECK: p3 = nullptr; + + int *p4 = p3; + // CHECK: int *p4 = p3; + + p4 = null; + // CHECK: p4 = nullptr; + + int i1 = 0; + // CHECK: int i1 = 0; + + int i2 = NULL; + // CHECK: int i2 = NULL; + + int i3 = null; + // CHECK: int i3 = null; + + int *p5, *p6, *p7; + p5 = p6 = p7 = NULL; + // CHECK: p5 = p6 = p7 = nullptr; +} + +struct Foo { + Foo(int *p = NULL) : m_p1(p) {} + // CHECK: Foo(int *p = nullptr) : m_p1(p) {} + + void bar(int *p = 0) {} + // CHECK: void bar(int *p = nullptr) {} + + void baz(int i = 0) {} + // CHECK: void baz(int i = 0) {} + + int *m_p1; + static int *m_p2; +}; + +int *Foo::m_p2 = NULL; +// CHECK: int *Foo::m_p2 = nullptr; + +template <typename T> +struct Bar { + Bar(T *p) : m_p(p) { + m_p = static_cast<T*>(NULL); + // CHECK: m_p = nullptr; + + m_p = static_cast<T*>(reinterpret_cast<int*>((void*)NULL)); + // CHECK: m_p = nullptr; + + m_p = static_cast<T*>(p ? p : static_cast<void*>(g_null)); + // CHECK: m_p = static_cast<T*>(p ? p : nullptr); + + T *p2 = static_cast<T*>(reinterpret_cast<int*>((void*)NULL)); + // CHECK: T *p2 = nullptr; + + m_p = NULL; + // CHECK: m_p = nullptr; + + int i = static_cast<int>(0.f); + // CHECK: int i = static_cast<int>(0.f); + T *i2 = static_cast<int>(0.f); + // CHECK: T *i2 = nullptr; + } + + T *m_p; +}; + +struct Baz { + Baz() : i(0) {} + int i; +}; + +void test_cxx_cases() { + Foo f(g_null); + // CHECK: Foo f(nullptr); + + f.bar(NULL); + // CHECK: f.bar(nullptr); + + f.baz(g_null); + // CHECK: f.baz(g_null); + + f.m_p1 = 0; + // CHECK: f.m_p1 = nullptr; + + Bar<int> b(g_null); + // CHECK: Bar<int> b(nullptr); + + Baz b2; + int Baz::*memptr(0); + // CHECK: int Baz::*memptr(nullptr); + + memptr = 0; + // CHECK: memptr = nullptr; +} + +void test_function_default_param1(void *p = 0); +// CHECK: void test_function_default_param1(void *p = nullptr); + +void test_function_default_param2(void *p = NULL); +// CHECK: void test_function_default_param2(void *p = nullptr); + +void test_function_default_param3(void *p = g_null); +// CHECK: void test_function_default_param3(void *p = nullptr); + +void test_function(int *p) {} +// CHECK: void test_function(int *p) {} + +void test_function_no_ptr_param(int i) {} + +void test_function_call() { + test_function(0); + // CHECK: test_function(nullptr); + + test_function(NULL); + // CHECK: test_function(nullptr); + + test_function(g_null); + // CHECK: test_function(nullptr); + + test_function_no_ptr_param(0); + // CHECK: test_function_no_ptr_param(0); +} + +char *test_function_return1() { + return 0; + // CHECK: return nullptr; +} + +void *test_function_return2() { + return NULL; + // CHECK: return nullptr; +} + +long *test_function_return3() { + return g_null; + // CHECK: return nullptr; +} + +int test_function_return4() { + return 0; + // CHECK: return 0; +} + +int test_function_return5() { + return NULL; + // CHECK: return NULL; +} + +int test_function_return6() { + return g_null; + // CHECK: return g_null; +} diff --git a/test/cpp11-migrate/UseNullptr/basic_failing.cpp b/test/cpp11-migrate/UseNullptr/basic_failing.cpp new file mode 100644 index 00000000..e2a21f42 --- /dev/null +++ b/test/cpp11-migrate/UseNullptr/basic_failing.cpp @@ -0,0 +1,28 @@ +// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp +// RUN: cpp11-migrate -use-nullptr %t.cpp -- -I %S +// RUN: FileCheck -input-file=%t.cpp %s +// REQUIRES: shell +// XFAIL: * + +#define NULL 0 + +template <typename T> +class A { +public: + A(T *p = NULL) {} + // CHECK: A(T *p = nullptr) {} + + void f() { + Ptr = NULL; + // CHECK: Ptr = nullptr; + } + + T *Ptr; +}; + +template <typename T> +T *f2(T *a = NULL) { + // CHECK: T *f2(T *a = nullptr) { + return a ? a : NULL; + // CHECK: return a ? a : nullptr; +} |