1 // RUN: %check_clang_tidy -std=c++14,c++17 -check-suffix=CXX-14-17 %s modernize-make-unique %t -- -- -I %S/Inputs/modernize-smart-ptr -D CXX_14_17=1
2 // RUN: %check_clang_tidy -std=c++20 -check-suffix=CXX-20 %s modernize-make-unique %t -- -- -I %S/Inputs/modernize-smart-ptr -D CXX_20=1
3 
4 #include "unique_ptr.h"
5 // CHECK-FIXES: #include <memory>
6 
7 struct NoCopyMoveCtor {
8 #ifdef CXX_20
9   // C++20 requires to see the default constructor, otherwise it is illgal.
10   NoCopyMoveCtor() = default;
11 #endif
12 #ifdef CXX_14_17
13   int a, b;
14 #endif
15   NoCopyMoveCtor(const NoCopyMoveCtor &) = delete; // implies move ctor is deleted
16 };
17 
18 struct NoCopyMoveCtorVisible {
19 #ifdef CXX_20
20   NoCopyMoveCtorVisible() = default;
21 #endif
22 private:
23   NoCopyMoveCtorVisible(const NoCopyMoveCtorVisible&) = default;
24   NoCopyMoveCtorVisible(NoCopyMoveCtorVisible&&) = default;
25 };
26 
27 struct OnlyMoveCtor {
28   OnlyMoveCtor() = default;
29   OnlyMoveCtor(OnlyMoveCtor&&) = default;
30   OnlyMoveCtor(const OnlyMoveCtor &) = delete;
31 };
32 
33 struct OnlyCopyCtor {
34 #ifdef CXX_20
35   OnlyCopyCtor() = default;
36 #endif
37   OnlyCopyCtor(const OnlyCopyCtor&) = default;
38   OnlyCopyCtor(OnlyCopyCtor&&) = delete;
39 };
40 
41 struct OnlyCopyCtorVisible {
42 #ifdef CXX_20
43   OnlyCopyCtorVisible() = default;
44 #endif
45   OnlyCopyCtorVisible(const OnlyCopyCtorVisible &) = default;
46 
47 private:
48   OnlyCopyCtorVisible(OnlyCopyCtorVisible &&) = default;
49 };
50 
51 struct ImplicitDeletedCopyCtor {
52   const OnlyMoveCtor ctor;
53 };
54 
f()55 void f() {
56   auto my_ptr = std::unique_ptr<int>(new int(1));
57   // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:17: warning: use std::make_unique instead
58   // CHECK-FIXES-CXX-14-17: auto my_ptr = std::make_unique<int>(1);
59   // CHECK-MESSAGES-CXX-20: :[[@LINE-3]]:17: warning: use std::make_unique instead
60   // CHECK-FIXES-CXX-20: auto my_ptr = std::make_unique<int>(1);
61 
62   // "new NoCopyMoveCtor{}" is processed differently in C++14/17 and C++20:
63   //   * In C++14/17, it is recognized as aggregate initialization,
64   //     no fixes will be generated although the generated fix is compilable.
65   //   * In C++20, it is is recognized as default constructor initialization
66   //     (similar to "new NoCopyMoveCtor()"), the check will emit the fix and
67   //     the fix is correct.
68   auto PNoCopyMoveCtor = std::unique_ptr<NoCopyMoveCtor>(new NoCopyMoveCtor{});
69   // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:26: warning: use std::make_unique instead
70   // CHECK-FIXES-CXX-14-17: auto PNoCopyMoveCtor = std::unique_ptr<NoCopyMoveCtor>(new NoCopyMoveCtor{});
71   // CHECK-MESSAGES-CXX-20: :[[@LINE-3]]:26: warning: use std::make_unique instead
72   // CHECK-FIXES-CXX-20: auto PNoCopyMoveCtor = std::make_unique<NoCopyMoveCtor>();
73 
74   auto PNoCopyMoveCtorVisible = std::unique_ptr<NoCopyMoveCtorVisible>(new NoCopyMoveCtorVisible{});
75   // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:33: warning: use std::make_unique instead
76   // CHECK-FIXES-CXX-14-17: auto PNoCopyMoveCtorVisible = std::unique_ptr<NoCopyMoveCtorVisible>(new NoCopyMoveCtorVisible{});
77   // CHECK-MESSAGES-CXX-20: :[[@LINE-3]]:33: warning: use std::make_unique instead
78   // CHECK-FIXES-CXX-20: auto PNoCopyMoveCtorVisible = std::make_unique<NoCopyMoveCtorVisible>();
79 
80   auto POnlyMoveCtor = std::unique_ptr<OnlyMoveCtor>(new OnlyMoveCtor{});
81   // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:24: warning: use std::make_unique instead
82   // CHECK-FIXES-CXX-14-17: auto POnlyMoveCtor = std::unique_ptr<OnlyMoveCtor>(new OnlyMoveCtor{});
83   // CHECK-MESSAGES-CXX-20: :[[@LINE-3]]:24: warning: use std::make_unique instead
84   // CHECK-FIXES-CXX-20: auto POnlyMoveCtor = std::make_unique<OnlyMoveCtor>();
85 
86   auto POnlyCopyCtor = std::unique_ptr<OnlyCopyCtor>(new OnlyCopyCtor{});
87   // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:24: warning: use std::make_unique instead
88   // CHECK-FIXES-CXX-14-17: auto POnlyCopyCtor = std::unique_ptr<OnlyCopyCtor>(new OnlyCopyCtor{});
89   // CHECK-MESSAGES-CXX-20: :[[@LINE-3]]:24: warning: use std::make_unique instead
90   // CHECK-FIXES-CXX-20: auto POnlyCopyCtor = std::make_unique<OnlyCopyCtor>();
91 
92   auto POnlyCopyCtorVisible = std::unique_ptr<OnlyCopyCtorVisible>(new OnlyCopyCtorVisible{});
93   // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:31: warning: use std::make_unique instead
94   // CHECK-FIXES-CXX-14-17: auto POnlyCopyCtorVisible = std::unique_ptr<OnlyCopyCtorVisible>(new OnlyCopyCtorVisible{});
95   // CHECK-MESSAGES-CXX-20: :[[@LINE-3]]:31: warning: use std::make_unique instead
96   // CHECK-FIXES-CXX-20: auto POnlyCopyCtorVisible = std::make_unique<OnlyCopyCtorVisible>();
97 
98   // This is aggregate initialization in C++20, no fix will be generated.
99   auto PImplicitDeletedCopyCtor = std::unique_ptr<ImplicitDeletedCopyCtor>(new ImplicitDeletedCopyCtor{});
100   // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:35: warning: use std::make_unique instead
101   // CHECK-FIXES-CXX-14-17: auto PImplicitDeletedCopyCtor = std::unique_ptr<ImplicitDeletedCopyCtor>(new ImplicitDeletedCopyCtor{});
102   // CHECK-MESSAGES-CXX-20: :[[@LINE-3]]:35: warning: use std::make_unique instead
103   // CHECK-FIXES-CXX-20: auto PImplicitDeletedCopyCtor = std::unique_ptr<ImplicitDeletedCopyCtor>(new ImplicitDeletedCopyCtor{});
104 
105 
106 #ifdef CXX_14_17
107   // FIXME: it is impossible to use make_unique for this case, the check should
108   // stop emitting the message.
109   auto PNoCopyMoveCtor2 = std::unique_ptr<NoCopyMoveCtor>(new NoCopyMoveCtor{1, 2});
110   // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:27: warning: use std::make_unique instead
111   // CHECK-FIXES-CXX-14-17: auto PNoCopyMoveCtor2 = std::unique_ptr<NoCopyMoveCtor>(new NoCopyMoveCtor{1, 2});
112 #endif
113 }
114