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