189a1d03eSRichard // RUN: %check_clang_tidy -std=c++14,c++17 -check-suffix=CXX-14-17 %s modernize-make-unique %t -- -- -I %S/Inputs/smart-ptr -D CXX_14_17=1
289a1d03eSRichard // RUN: %check_clang_tidy -std=c++20 -check-suffix=CXX-20 %s modernize-make-unique %t -- -- -I %S/Inputs/smart-ptr -D CXX_20=1
389a1d03eSRichard 
489a1d03eSRichard #include "unique_ptr.h"
589a1d03eSRichard // CHECK-FIXES: #include <memory>
689a1d03eSRichard 
789a1d03eSRichard struct NoCopyMoveCtor {
889a1d03eSRichard #ifdef CXX_20
989a1d03eSRichard   // C++20 requires to see the default constructor, otherwise it is illgal.
1089a1d03eSRichard   NoCopyMoveCtor() = default;
1189a1d03eSRichard #endif
1289a1d03eSRichard #ifdef CXX_14_17
1389a1d03eSRichard   int a, b;
1489a1d03eSRichard #endif
1589a1d03eSRichard   NoCopyMoveCtor(const NoCopyMoveCtor &) = delete; // implies move ctor is deleted
1689a1d03eSRichard };
1789a1d03eSRichard 
1889a1d03eSRichard struct NoCopyMoveCtorVisible {
1989a1d03eSRichard #ifdef CXX_20
2089a1d03eSRichard   NoCopyMoveCtorVisible() = default;
2189a1d03eSRichard #endif
2289a1d03eSRichard private:
2389a1d03eSRichard   NoCopyMoveCtorVisible(const NoCopyMoveCtorVisible&) = default;
2489a1d03eSRichard   NoCopyMoveCtorVisible(NoCopyMoveCtorVisible&&) = default;
2589a1d03eSRichard };
2689a1d03eSRichard 
2789a1d03eSRichard struct OnlyMoveCtor {
2889a1d03eSRichard   OnlyMoveCtor() = default;
2989a1d03eSRichard   OnlyMoveCtor(OnlyMoveCtor&&) = default;
3089a1d03eSRichard   OnlyMoveCtor(const OnlyMoveCtor &) = delete;
3189a1d03eSRichard };
3289a1d03eSRichard 
3389a1d03eSRichard struct OnlyCopyCtor {
3489a1d03eSRichard #ifdef CXX_20
3589a1d03eSRichard   OnlyCopyCtor() = default;
3689a1d03eSRichard #endif
3789a1d03eSRichard   OnlyCopyCtor(const OnlyCopyCtor&) = default;
3889a1d03eSRichard   OnlyCopyCtor(OnlyCopyCtor&&) = delete;
3989a1d03eSRichard };
4089a1d03eSRichard 
4189a1d03eSRichard struct OnlyCopyCtorVisible {
4289a1d03eSRichard #ifdef CXX_20
4389a1d03eSRichard   OnlyCopyCtorVisible() = default;
4489a1d03eSRichard #endif
4589a1d03eSRichard   OnlyCopyCtorVisible(const OnlyCopyCtorVisible &) = default;
4689a1d03eSRichard 
4789a1d03eSRichard private:
4889a1d03eSRichard   OnlyCopyCtorVisible(OnlyCopyCtorVisible &&) = default;
4989a1d03eSRichard };
5089a1d03eSRichard 
5189a1d03eSRichard struct ImplicitDeletedCopyCtor {
5289a1d03eSRichard   const OnlyMoveCtor ctor;
5389a1d03eSRichard };
5489a1d03eSRichard 
f()5589a1d03eSRichard void f() {
5689a1d03eSRichard   auto my_ptr = std::unique_ptr<int>(new int(1));
5789a1d03eSRichard   // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:17: warning: use std::make_unique instead
5889a1d03eSRichard   // CHECK-FIXES-CXX-14-17: auto my_ptr = std::make_unique<int>(1);
5989a1d03eSRichard   // CHECK-MESSAGES-CXX-20: :[[@LINE-3]]:17: warning: use std::make_unique instead
6089a1d03eSRichard   // CHECK-FIXES-CXX-20: auto my_ptr = std::make_unique<int>(1);
6189a1d03eSRichard 
6289a1d03eSRichard   // "new NoCopyMoveCtor{}" is processed differently in C++14/17 and C++20:
6389a1d03eSRichard   //   * In C++14/17, it is recognized as aggregate initialization,
6489a1d03eSRichard   //     no fixes will be generated although the generated fix is compilable.
65*678e3ee1SFangrui Song   //   * In C++20, it is recognized as default constructor initialization
6689a1d03eSRichard   //     (similar to "new NoCopyMoveCtor()"), the check will emit the fix and
6789a1d03eSRichard   //     the fix is correct.
6889a1d03eSRichard   auto PNoCopyMoveCtor = std::unique_ptr<NoCopyMoveCtor>(new NoCopyMoveCtor{});
6989a1d03eSRichard   // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:26: warning: use std::make_unique instead
7089a1d03eSRichard   // CHECK-FIXES-CXX-14-17: auto PNoCopyMoveCtor = std::unique_ptr<NoCopyMoveCtor>(new NoCopyMoveCtor{});
7189a1d03eSRichard   // CHECK-MESSAGES-CXX-20: :[[@LINE-3]]:26: warning: use std::make_unique instead
7289a1d03eSRichard   // CHECK-FIXES-CXX-20: auto PNoCopyMoveCtor = std::make_unique<NoCopyMoveCtor>();
7389a1d03eSRichard 
7489a1d03eSRichard   auto PNoCopyMoveCtorVisible = std::unique_ptr<NoCopyMoveCtorVisible>(new NoCopyMoveCtorVisible{});
7589a1d03eSRichard   // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:33: warning: use std::make_unique instead
7689a1d03eSRichard   // CHECK-FIXES-CXX-14-17: auto PNoCopyMoveCtorVisible = std::unique_ptr<NoCopyMoveCtorVisible>(new NoCopyMoveCtorVisible{});
7789a1d03eSRichard   // CHECK-MESSAGES-CXX-20: :[[@LINE-3]]:33: warning: use std::make_unique instead
7889a1d03eSRichard   // CHECK-FIXES-CXX-20: auto PNoCopyMoveCtorVisible = std::make_unique<NoCopyMoveCtorVisible>();
7989a1d03eSRichard 
8089a1d03eSRichard   auto POnlyMoveCtor = std::unique_ptr<OnlyMoveCtor>(new OnlyMoveCtor{});
8189a1d03eSRichard   // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:24: warning: use std::make_unique instead
8289a1d03eSRichard   // CHECK-FIXES-CXX-14-17: auto POnlyMoveCtor = std::unique_ptr<OnlyMoveCtor>(new OnlyMoveCtor{});
8389a1d03eSRichard   // CHECK-MESSAGES-CXX-20: :[[@LINE-3]]:24: warning: use std::make_unique instead
8489a1d03eSRichard   // CHECK-FIXES-CXX-20: auto POnlyMoveCtor = std::make_unique<OnlyMoveCtor>();
8589a1d03eSRichard 
8689a1d03eSRichard   auto POnlyCopyCtor = std::unique_ptr<OnlyCopyCtor>(new OnlyCopyCtor{});
8789a1d03eSRichard   // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:24: warning: use std::make_unique instead
8889a1d03eSRichard   // CHECK-FIXES-CXX-14-17: auto POnlyCopyCtor = std::unique_ptr<OnlyCopyCtor>(new OnlyCopyCtor{});
8989a1d03eSRichard   // CHECK-MESSAGES-CXX-20: :[[@LINE-3]]:24: warning: use std::make_unique instead
9089a1d03eSRichard   // CHECK-FIXES-CXX-20: auto POnlyCopyCtor = std::make_unique<OnlyCopyCtor>();
9189a1d03eSRichard 
9289a1d03eSRichard   auto POnlyCopyCtorVisible = std::unique_ptr<OnlyCopyCtorVisible>(new OnlyCopyCtorVisible{});
9389a1d03eSRichard   // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:31: warning: use std::make_unique instead
9489a1d03eSRichard   // CHECK-FIXES-CXX-14-17: auto POnlyCopyCtorVisible = std::unique_ptr<OnlyCopyCtorVisible>(new OnlyCopyCtorVisible{});
9589a1d03eSRichard   // CHECK-MESSAGES-CXX-20: :[[@LINE-3]]:31: warning: use std::make_unique instead
9689a1d03eSRichard   // CHECK-FIXES-CXX-20: auto POnlyCopyCtorVisible = std::make_unique<OnlyCopyCtorVisible>();
9789a1d03eSRichard 
9889a1d03eSRichard   // This is aggregate initialization in C++20, no fix will be generated.
9989a1d03eSRichard   auto PImplicitDeletedCopyCtor = std::unique_ptr<ImplicitDeletedCopyCtor>(new ImplicitDeletedCopyCtor{});
10089a1d03eSRichard   // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:35: warning: use std::make_unique instead
10189a1d03eSRichard   // CHECK-FIXES-CXX-14-17: auto PImplicitDeletedCopyCtor = std::unique_ptr<ImplicitDeletedCopyCtor>(new ImplicitDeletedCopyCtor{});
10289a1d03eSRichard   // CHECK-MESSAGES-CXX-20: :[[@LINE-3]]:35: warning: use std::make_unique instead
10389a1d03eSRichard   // CHECK-FIXES-CXX-20: auto PImplicitDeletedCopyCtor = std::unique_ptr<ImplicitDeletedCopyCtor>(new ImplicitDeletedCopyCtor{});
10489a1d03eSRichard 
10589a1d03eSRichard 
10689a1d03eSRichard #ifdef CXX_14_17
10789a1d03eSRichard   // FIXME: it is impossible to use make_unique for this case, the check should
10889a1d03eSRichard   // stop emitting the message.
10989a1d03eSRichard   auto PNoCopyMoveCtor2 = std::unique_ptr<NoCopyMoveCtor>(new NoCopyMoveCtor{1, 2});
11089a1d03eSRichard   // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:27: warning: use std::make_unique instead
11189a1d03eSRichard   // CHECK-FIXES-CXX-14-17: auto PNoCopyMoveCtor2 = std::unique_ptr<NoCopyMoveCtor>(new NoCopyMoveCtor{1, 2});
11289a1d03eSRichard #endif
11389a1d03eSRichard }
114