340 lines · cpp
1// RUN: %check_clang_tidy %s modernize-make-shared %t -- -- -I %S/Inputs/smart-ptr2 3#include "shared_ptr.h"4// CHECK-FIXES: #include <memory>5 6struct Base {7 Base();8 Base(int, int);9};10 11struct Derived : public Base {12 Derived();13 Derived(int, int);14};15 16struct APair {17 int a, b;18};19 20struct DPair {21 DPair() : a(0), b(0) {}22 DPair(int x, int y) : a(y), b(x) {}23 int a, b;24};25 26struct Empty {};27 28template <class T>29using shared_ptr_ = std::shared_ptr<T>;30 31void *operator new(__SIZE_TYPE__ Count, void *Ptr);32 33int g(std::shared_ptr<int> P);34 35std::shared_ptr<Base> getPointer() {36 return std::shared_ptr<Base>(new Base);37 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use std::make_shared instead38 // CHECK-FIXES: return std::make_shared<Base>();39}40 41std::shared_ptr<Base> getPointerValue() {42 return std::shared_ptr<Base>(new Base());43 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use std::make_shared instead44 // CHECK-FIXES: return std::make_shared<Base>();45}46 47void basic() {48 std::shared_ptr<int> P1 = std::shared_ptr<int>(new int());49 // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared]50 // CHECK-FIXES: std::shared_ptr<int> P1 = std::make_shared<int>();51 std::shared_ptr<int> P2 = std::shared_ptr<int>(new int);52 53 P1.reset(new int());54 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead [modernize-make-shared]55 // CHECK-FIXES: P1 = std::make_shared<int>();56 P1.reset(new int);57 58 P1 = std::shared_ptr<int>(new int());59 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead [modernize-make-shared]60 // CHECK-FIXES: P1 = std::make_shared<int>();61 P1 = std::shared_ptr<int>(new int);62 63 // Without parenthesis, default initialization.64 std::shared_ptr<int> P3 = std::shared_ptr<int>(new int);65 66 P2.reset(new int());67 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead [modernize-make-shared]68 // CHECK-FIXES: P2 = std::make_shared<int>();69 P2.reset(new int);70 71 P2 = std::shared_ptr<int>(new int());72 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead [modernize-make-shared]73 // CHECK-FIXES: P2 = std::make_shared<int>();74 P2 = std::shared_ptr<int>(new int);75 76 // With auto.77 auto P4 = std::shared_ptr<int>(new int());78 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_shared instead79 // CHECK-FIXES: auto P4 = std::make_shared<int>();80 auto P5 = std::shared_ptr<int>(new int);81 82 std::shared_ptr<int> P6 = std::shared_ptr<int>((new int()));83 // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared]84 // CHECK-FIXES: std::shared_ptr<int> P6 = std::make_shared<int>();85 std::shared_ptr<int> P7 = std::shared_ptr<int>((new int));86 87 P4.reset((((new int()))));88 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead [modernize-make-shared]89 // CHECK-FIXES: P4 = std::make_shared<int>();90 P4.reset((((new int))));91 92 P4 = std::shared_ptr<int>(((new int())));93 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead [modernize-make-shared]94 // CHECK-FIXES: P4 = std::make_shared<int>();95 P4 = std::shared_ptr<int>(((new int)));96 97 {98 // No std.99 using namespace std;100 shared_ptr<int> Q = shared_ptr<int>(new int());101 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use std::make_shared instead102 // CHECK-FIXES: shared_ptr<int> Q = std::make_shared<int>();103 shared_ptr<int> P = shared_ptr<int>(new int);104 105 Q = shared_ptr<int>(new int());106 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead107 // CHECK-FIXES: Q = std::make_shared<int>();108 Q = shared_ptr<int>(new int);109 }110 111 std::shared_ptr<int> R(new int());112 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_shared instead113 // CHECK-FIXES: std::shared_ptr<int> R = std::make_shared<int>();114 std::shared_ptr<int> S(new int);115 116 // Create the shared_ptr as a parameter to a function.117 int T = g(std::shared_ptr<int>(new int()));118 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_shared instead119 // CHECK-FIXES: int T = g(std::make_shared<int>());120 T = g(std::shared_ptr<int>(new int));121 122 // Only replace if the type in the template is the same as the type returned123 // by the new operator.124 auto Pderived = std::shared_ptr<Base>(new Derived());125 auto PderivedNoparen = std::shared_ptr<Base>(new Derived);126 127 // OK to replace for reset and assign128 Pderived.reset(new Derived());129 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use std::make_shared instead130 // CHECK-FIXES: Pderived = std::make_shared<Derived>();131 Pderived.reset(new Derived);132 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use std::make_shared instead133 // CHECK-FIXES: Pderived = std::make_shared<Derived>();134 135 Pderived = std::shared_ptr<Derived>(new Derived());136 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use std::make_shared instead137 // CHECK-FIXES: Pderived = std::make_shared<Derived>();138 Pderived = std::shared_ptr<Derived>(new Derived);139 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use std::make_shared instead140 // CHECK-FIXES: Pderived = std::make_shared<Derived>();141 142 // FIXME: OK to replace if assigned to shared_ptr<Base>143 Pderived = std::shared_ptr<Base>(new Derived());144 Pderived = std::shared_ptr<Base>(new Derived);145 146 // FIXME: OK to replace when auto is not used147 std::shared_ptr<Base> PBase = std::shared_ptr<Base>(new Derived());148 std::shared_ptr<Base> PBase2 = std::shared_ptr<Base>(new Derived);149 150 // The pointer is returned by the function, nothing to do.151 std::shared_ptr<Base> RetPtr = getPointer();152 std::shared_ptr<Base> RetPtr2 = getPointerValue();153 154 // This emulates std::move.155 std::shared_ptr<int> Move = static_cast<std::shared_ptr<int> &&>(P1);156 157 // Placement arguments should not be removed.158 int *PInt = new int;159 std::shared_ptr<int> Placement = std::shared_ptr<int>(new (PInt) int{3});160 Placement.reset(new (PInt) int{3});161 Placement = std::shared_ptr<int>(new (PInt) int{3});162 163 std::shared_ptr<int> PlacementNoparen = std::shared_ptr<int>(new (PInt) int);164 PlacementNoparen.reset(new (PInt) int);165 PlacementNoparen = std::shared_ptr<int>(new (PInt) int);166}167 168// Calling make_smart_ptr from within a member function of a type with a169// private or protected constructor would be ill-formed.170class Private {171private:172 Private(int z) {}173 174public:175 Private() {}176 void create() {177 auto callsPublic = std::shared_ptr<Private>(new Private);178 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_shared instead179 // CHECK-FIXES: auto callsPublic = std::make_shared<Private>();180 auto ptr = std::shared_ptr<Private>(new Private(42));181 ptr.reset(new Private(42));182 ptr = std::shared_ptr<Private>(new Private(42));183 }184 185 virtual ~Private();186};187 188class Protected {189protected:190 Protected() {}191 192public:193 Protected(int, int) {}194 void create() {195 auto callsPublic = std::shared_ptr<Protected>(new Protected(1, 2));196 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_shared instead197 // CHECK-FIXES: auto callsPublic = std::make_shared<Protected>(1, 2);198 auto ptr = std::shared_ptr<Protected>(new Protected);199 ptr.reset(new Protected);200 ptr = std::shared_ptr<Protected>(new Protected);201 }202};203 204void initialization(int T, Base b) {205 // Test different kinds of initialization of the pointee.206 207 // Direct initialization with parenthesis.208 std::shared_ptr<DPair> PDir1 = std::shared_ptr<DPair>(new DPair(1, T));209 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead210 // CHECK-FIXES: std::shared_ptr<DPair> PDir1 = std::make_shared<DPair>(1, T);211 PDir1.reset(new DPair(1, T));212 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead213 // CHECK-FIXES: PDir1 = std::make_shared<DPair>(1, T);214 215 // Direct initialization with braces.216 std::shared_ptr<DPair> PDir2 = std::shared_ptr<DPair>(new DPair{2, T});217 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead218 // CHECK-FIXES: std::shared_ptr<DPair> PDir2 = std::make_shared<DPair>(2, T);219 PDir2.reset(new DPair{2, T});220 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead221 // CHECK-FIXES: PDir2 = std::make_shared<DPair>(2, T);222 223 // Aggregate initialization.224 std::shared_ptr<APair> PAggr = std::shared_ptr<APair>(new APair{T, 1});225 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead226 // CHECK-FIXES: std::shared_ptr<APair> PAggr = std::make_shared<APair>(APair{T, 1});227 PAggr.reset(new APair{T, 1});228 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead229 // CHECK-FIXES: PAggr = std::make_shared<APair>(APair{T, 1});230 231 // Test different kinds of initialization of the pointee, when the shared_ptr232 // is initialized with braces.233 234 // Direct initialization with parenthesis.235 std::shared_ptr<DPair> PDir3 = std::shared_ptr<DPair>{new DPair(3, T)};236 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead237 // CHECK-FIXES: std::shared_ptr<DPair> PDir3 = std::make_shared<DPair>(3, T);238 239 // Direct initialization with braces.240 std::shared_ptr<DPair> PDir4 = std::shared_ptr<DPair>{new DPair{4, T}};241 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead242 // CHECK-FIXES: std::shared_ptr<DPair> PDir4 = std::make_shared<DPair>(4, T);243 244 // Aggregate initialization.245 std::shared_ptr<APair> PAggr2 = std::shared_ptr<APair>{new APair{T, 2}};246 // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_shared instead247 // CHECK-FIXES: std::shared_ptr<APair> PAggr2 = std::make_shared<APair>(APair{T, 2});248 249 // Direct initialization with parenthesis, without arguments.250 std::shared_ptr<DPair> PDir5 = std::shared_ptr<DPair>(new DPair());251 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead252 // CHECK-FIXES: std::shared_ptr<DPair> PDir5 = std::make_shared<DPair>();253 254 // Direct initialization with braces, without arguments.255 std::shared_ptr<DPair> PDir6 = std::shared_ptr<DPair>(new DPair{});256 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead257 // CHECK-FIXES: std::shared_ptr<DPair> PDir6 = std::make_shared<DPair>();258 259 // Aggregate initialization without arguments.260 std::shared_ptr<Empty> PEmpty = std::shared_ptr<Empty>(new Empty{});261 // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_shared instead262 // CHECK-FIXES: std::shared_ptr<Empty> PEmpty = std::make_shared<Empty>(Empty{});263}264 265void aliases() {266 typedef std::shared_ptr<int> IntPtr;267 IntPtr Typedef = IntPtr(new int());268 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use std::make_shared instead269 // CHECK-FIXES: IntPtr Typedef = std::make_shared<int>();270 IntPtr Typedef2 = IntPtr(new int);271 272 // We use 'bool' instead of '_Bool'.273 typedef std::shared_ptr<bool> BoolPtr;274 BoolPtr BoolType = BoolPtr(new bool());275 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::make_shared instead276 // CHECK-FIXES: BoolPtr BoolType = std::make_shared<bool>();277 BoolPtr BoolType2 = BoolPtr(new bool);278 279 // We use 'Base' instead of 'struct Base'.280 typedef std::shared_ptr<Base> BasePtr;281 BasePtr StructType = BasePtr(new Base);282// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_shared instead283// CHECK-FIXES: BasePtr StructType = std::make_shared<Base>();284 285#define PTR shared_ptr<int>286 std::shared_ptr<int> Macro = std::PTR(new int());287 // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_shared instead288 // CHECK-FIXES: std::shared_ptr<int> Macro = std::make_shared<int>();289 std::shared_ptr<int> Macro2 = std::PTR(new int);290#undef PTR291 292 std::shared_ptr<int> Using = shared_ptr_<int>(new int());293 // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_shared instead294 // CHECK-FIXES: std::shared_ptr<int> Using = std::make_shared<int>();295 std::shared_ptr<int> Using2 = shared_ptr_<int>(new int);296}297 298void whitespaces() {299 // clang-format off300 auto Space = std::shared_ptr <int>(new int());301 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use std::make_shared instead302 // CHECK-FIXES: auto Space = std::make_shared<int>();303 auto Space2 = std::shared_ptr <int>(new int);304 305 auto Spaces = std :: shared_ptr <int>(new int());306 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use std::make_shared instead307 // CHECK-FIXES: auto Spaces = std::make_shared<int>();308 auto Spaces2 = std :: shared_ptr <int>(new int);309 // clang-format on310}311 312void nesting() {313 auto Nest = std::shared_ptr<std::shared_ptr<int>>(new std::shared_ptr<int>(new int));314 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use std::make_shared instead315 // CHECK-FIXES: auto Nest = std::make_shared<std::shared_ptr<int>>(new int);316 Nest.reset(new std::shared_ptr<int>(new int));317 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead318 // CHECK-FIXES: Nest = std::make_shared<std::shared_ptr<int>>(new int);319 Nest->reset(new int());320 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead321 // CHECK-FIXES: *Nest = std::make_shared<int>();322 Nest->reset(new int);323}324 325void reset() {326 std::shared_ptr<int> P;327 P.reset();328 P.reset(nullptr);329 P.reset(new int());330 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use std::make_shared instead331 // CHECK-FIXES: P = std::make_shared<int>();332 P.reset(new int);333 334 auto Q = &P;335 Q->reset(new int());336 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead337 // CHECK-FIXES: *Q = std::make_shared<int>();338 Q->reset(new int);339}340