Dosi-Dough created this revision.
Dosi-Dough added reviewers: EricWF, JonasToth.
Dosi-Dough added a project: clang-tools-extra.
Herald added subscribers: xazax.hun, mgorny.
based on abseil tip of the week 126 https://abseil.io/tips/126
Created a check which looks for instances of a factory function that uses a
non-public constructor and return a std::unique_ptr.
Repository:
rCTE Clang Tools Extra
https://reviews.llvm.org/D57435
Files:
clang-tidy/.DS_Store
clang-tidy/abseil/.DS_Store
clang-tidy/abseil/AbseilTidyModule.cpp
clang-tidy/abseil/CMakeLists.txt
clang-tidy/abseil/WrapUniqueCheck.cpp
clang-tidy/abseil/WrapUniqueCheck.h
docs/ReleaseNotes.rst
docs/clang-tidy/checks/abseil-wrap-unique.rst
docs/clang-tidy/checks/list.rst
test/.DS_Store
test/clang-tidy/.DS_Store
test/clang-tidy/abseil-wrap-unique.cpp
Index: test/clang-tidy/abseil-wrap-unique.cpp
===
--- /dev/null
+++ test/clang-tidy/abseil-wrap-unique.cpp
@@ -0,0 +1,91 @@
+// RUN: %check_clang_tidy %s abseil-wrap-unique %t
+
+
+namespace std {
+
+template
+class default_delete {};
+
+template >
+class unique_ptr {
+public:
+ unique_ptr() {}
+ unique_ptr(type *ptr) {}
+ unique_ptr(const unique_ptr &t) = delete;
+ unique_ptr(unique_ptr &&t) {}
+ ~unique_ptr() {}
+ type &operator*() { return *ptr; }
+ type *operator->() { return ptr; }
+ type *release() { return ptr; }
+ void reset() {}
+ void reset(type *pt) {}
+ void reset(type pt) {}
+ unique_ptr &operator=(unique_ptr &&) { return *this; }
+ template
+ unique_ptr &operator=(unique_ptr &&) { return *this; }
+
+private:
+ type *ptr;
+};
+} // namespace std
+
+
+class A {
+ public:
+ static A* NewA() {
+return new A();
+ }
+
+ private:
+ A() {}
+};
+
+class B {
+ public:
+ static B* NewB(int bIn) {
+return new B();
+ }
+
+ private:
+ B() {}
+};
+
+struct C {
+ int x;
+ int y;
+};
+/*
+std::unique_ptr returnPointer() {
+ return std::unique_ptr(A::NewA());
+}
+*/
+void positives() {
+ std::unique_ptr a;
+ a.reset(A::NewA());
+ //CHECK-MESSAGE: :[[@LINE-1]]:3: warning: prefer absl::WrapUnique for resetting unique_ptr [abseil-wrap-unique]
+ //CHECK-FIXES: a = absl::WrapUnique(A::NewA())
+
+ std::unique_ptr b(A::NewA());
+ //CHECK-MESSAGE: :[[@LINE-1]]:3: warning: Perfer absl::WrapUnique to constructing unique_ptr [abseil-wrap-unique]
+ //CHECK-FIXES: auto b = absl::WrapUnique(A::NewA())
+
+ int cIn;
+ std::unique_ptr c(B::NewB(cIn));
+ //CHECK-MESSAGE: :[[@LINE-1]]:3: warning: Perfer absl::WrapUnique to constructing unique_ptr [abseil-wrap-unique]
+ //CHECK-FIXES: auto c = absl::WrapUnique(B::NewB(cIn))
+
+ int dIn;
+ std::unique_ptr d;
+ d.reset(B::NewB(dIn));
+ //CHECK-MESSAGE: :[[@LINE-1]]:3: warning: prefer absl::WrapUnique for resetting unique_ptr [abseil-wrap-unique]
+ //CHECK-FIXES: d = absl::WrapUnique(B::NewB(dIn))
+
+ auto e = std::unique_ptr(A::NewA());
+ //CHECK-MESSAGE: :[[@LINE-1]]:3: warning: prefer absl::WrapUnique for resetting unique_ptr [abseil-wrap-unique]
+ //CHECK-FIXES: e = absl::WrapUnique(A::NewA())
+
+ //std::unique_ptr e(new int[2] {1,2});
+
+}
+
+
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -17,6 +17,7 @@
abseil-str-cat-append
abseil-string-find-startswith
abseil-upgrade-duration-conversions
+ abseil-wrap-unique
android-cloexec-accept
android-cloexec-accept4
android-cloexec-creat
Index: docs/clang-tidy/checks/abseil-wrap-unique.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/abseil-wrap-unique.rst
@@ -0,0 +1,34 @@
+.. title:: clang-tidy - abseil-wrap-unique
+
+abseil-wrap-unique
+==
+
+Checks for instances of static function within a class being called and
+returning a std:unique_ptr type. Also checks for instances where reset
+is called on a static function which returns std::unique_ptr.
+
+.. code-block:: c++
+
+ class A {
+public:
+ static A* NewA() {
+return new A();
+ }
+
+private:
+ A() {}
+ };
+
+ std::unique_ptr a;
+
+ //Original - reset called with a static function returning a std::unqiue_ptr
+ a.reset(A::NewA());
+
+ //Suggested - reset ptr with absl::WrapUnique
+ a = absl::WrapUnique(A::NewA());
+
+ //Original - std::unique_ptr initialized with static function
+ std::unique_ptr b(A::NewA());
+
+ //Suggested - initialize with absl::WrapUnique instead
+ auto b = absl::WrapUnique(A::NewA())
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -67,6 +67,13 @@
Improvements to clang-tidy
--
+- New :doc:`abseil-wrap-unique
+ ` check.
+
+ Looks for instances of factory functions which uses a non-public constructor