aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorEdwin Vane <edwin.vane@intel.com>2013-01-22 18:31:49 +0000
committerEdwin Vane <edwin.vane@intel.com>2013-01-22 18:31:49 +0000
commite93d6aec4dee01889ecdf6b8f2fdb14fd33cfa1d (patch)
treecfb2564db4318f37240599c46ecace31824e0d4d /test
parentea1c746944afb7b0aefa0094de8fc8bc7862c085 (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.cpp47
-rw-r--r--test/cpp11-migrate/UseNullptr/Inputs/basic.h2
-rw-r--r--test/cpp11-migrate/UseNullptr/basic.cpp181
-rw-r--r--test/cpp11-migrate/UseNullptr/basic_failing.cpp28
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;
+}