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