1*89a1d03eSRichard // RUN: %check_clang_tidy %s cppcoreguidelines-owning-memory %t 2*89a1d03eSRichard 3*89a1d03eSRichard namespace gsl { 4*89a1d03eSRichard template <typename T> 5*89a1d03eSRichard using owner = T; 6*89a1d03eSRichard } 7*89a1d03eSRichard 8*89a1d03eSRichard namespace std { 9*89a1d03eSRichard 10*89a1d03eSRichard // Not actually a vector, but more a dynamic, fixed size array. Just to demonstrate 11*89a1d03eSRichard // functionality or the lack of the same. 12*89a1d03eSRichard template <typename T> 13*89a1d03eSRichard class vector { 14*89a1d03eSRichard public: vector(unsigned long size,T val)15*89a1d03eSRichard vector(unsigned long size, T val) : data{new T[size]}, size{size} { 16*89a1d03eSRichard for (unsigned long i = 0ul; i < size; ++i) { 17*89a1d03eSRichard data[i] = val; 18*89a1d03eSRichard } 19*89a1d03eSRichard } 20*89a1d03eSRichard begin()21*89a1d03eSRichard T *begin() { return data; } end()22*89a1d03eSRichard T *end() { return &data[size]; } operator [](unsigned long index)23*89a1d03eSRichard T &operator[](unsigned long index) { return data[index]; } 24*89a1d03eSRichard 25*89a1d03eSRichard private: 26*89a1d03eSRichard T *data; 27*89a1d03eSRichard unsigned long size; 28*89a1d03eSRichard }; 29*89a1d03eSRichard 30*89a1d03eSRichard } // namespace std 31*89a1d03eSRichard 32*89a1d03eSRichard // All of the following codesnippets should be valid with appropriate 'owner<>' analysis, 33*89a1d03eSRichard // but currently the type information of 'gsl::owner<>' gets lost in typededuction. main()34*89a1d03eSRichardint main() { 35*89a1d03eSRichard std::vector<gsl::owner<int *>> OwnerStdVector(100, nullptr); 36*89a1d03eSRichard 37*89a1d03eSRichard // Rangebased looping in resource vector. 38*89a1d03eSRichard for (auto *Element : OwnerStdVector) { 39*89a1d03eSRichard Element = new int(42); 40*89a1d03eSRichard // CHECK-NOTES: [[@LINE-1]]:5: warning: assigning newly created 'gsl::owner<>' to non-owner 'int *' 41*89a1d03eSRichard } 42*89a1d03eSRichard for (auto *Element : OwnerStdVector) { 43*89a1d03eSRichard delete Element; 44*89a1d03eSRichard // CHECK-NOTES: [[@LINE-1]]:5: warning: deleting a pointer through a type that is not marked 'gsl::owner<>'; consider using a smart pointer instead 45*89a1d03eSRichard // CHECK-NOTES: [[@LINE-3]]:8: note: variable declared here 46*89a1d03eSRichard } 47*89a1d03eSRichard 48*89a1d03eSRichard // Indexbased looping in resource vector. 49*89a1d03eSRichard for (int i = 0; i < 100; ++i) { 50*89a1d03eSRichard OwnerStdVector[i] = new int(42); 51*89a1d03eSRichard // CHECK-NOTES: [[@LINE-1]]:5: warning: assigning newly created 'gsl::owner<>' to non-owner 'int *' 52*89a1d03eSRichard } 53*89a1d03eSRichard for (int i = 0; i < 100; ++i) { 54*89a1d03eSRichard delete OwnerStdVector[i]; 55*89a1d03eSRichard // CHECK-NOTES: [[@LINE-1]]:5: warning: deleting a pointer through a type that is not marked 'gsl::owner<>'; consider using a smart pointer instead 56*89a1d03eSRichard // CHECK-NOTES: [[@LINE-21]]:3: note: variable declared here 57*89a1d03eSRichard // A note gets emitted here pointing to the return value of the operator[] from the 58*89a1d03eSRichard // vector implementation. Maybe this is considered misleading. 59*89a1d03eSRichard } 60*89a1d03eSRichard 61*89a1d03eSRichard return 0; 62*89a1d03eSRichard } 63