xref: /llvm-project/clang/test/SemaCXX/attr-gsl-owner-pointer-std.cpp (revision f8f41bf92c92ebc9b113a2a573d12880b86d5af3)
1 // RUN: %clang_cc1 -ast-dump %s | \
2 // RUN: FileCheck --implicit-check-not OwnerAttr --implicit-check-not PointerAttr %s
3 
4 // Test attribute inference for types in the standard library.
5 namespace std {
6 // Attributes are inferred for a (complete) class.
7 class any {
8   // CHECK: CXXRecordDecl {{.*}} any
9   // CHECK: OwnerAttr {{.*}}
10 };
11 
12 // Attributes are inferred for instantiations of a complete template.
13 template <typename T>
14 class vector {
15 public:
16   class iterator {};
17   // CHECK: ClassTemplateDecl {{.*}} vector
18   // CHECK: OwnerAttr {{.*}}
19   // CHECK: CXXRecordDecl {{.*}} iterator
20   // CHECK: PointerAttr {{.*}}
21   // CHECK: ClassTemplateSpecializationDecl {{.*}} vector
22   // CHECK: TemplateArgument type 'int'
23   // CHECK: OwnerAttr
24   // CHECK: CXXRecordDecl {{.*}} iterator
25   // CHECK: PointerAttr {{.*}}
26 };
27 static_assert(sizeof(vector<int>), "");           // Force instantiation.
28 static_assert(sizeof(vector<int>::iterator), ""); // Force instantiation.
29 
30 template <>
31 class vector<bool> {};
32 // CHECK: ClassTemplateSpecializationDecl {{.*}} vector
33 // CHECK: OwnerAttr {{.*}}
34 
35 // If std::container::iterator is a using declaration, attributes are inferred
36 // for the underlying class.
37 template <typename T>
38 class __set_iterator {};
39 // CHECK: ClassTemplateDecl {{.*}} __set_iterator
40 // CHECK: PointerAttr
41 // CHECK: ClassTemplateSpecializationDecl {{.*}} __set_iterator
42 // CHECK: TemplateArgument type 'int'
43 // CHECK: PointerAttr
44 
45 template <typename T>
46 class set {
47   // CHECK: ClassTemplateDecl {{.*}} set
48   // CHECK: OwnerAttr {{.*}}
49   // CHECK: ClassTemplateSpecializationDecl {{.*}} set
50   // CHECK: OwnerAttr {{.*}}
51 public:
52   using iterator = __set_iterator<T>;
53 };
54 static_assert(sizeof(set<int>::iterator), ""); // Force instantiation.
55 
56 // If std::container::iterator is a typedef, attributes are inferred for the
57 // underlying class.
58 template <typename T>
59 class __map_iterator {};
60 // CHECK: ClassTemplateDecl {{.*}} __map_iterator
61 // CHECK: PointerAttr
62 // CHECK: ClassTemplateSpecializationDecl {{.*}} __map_iterator
63 // CHECK: TemplateArgument type 'int'
64 // CHECK: PointerAttr
65 
66 template <typename T>
67 class map {
68   // CHECK: ClassTemplateDecl {{.*}} map
69   // CHECK: OwnerAttr {{.*}}
70   // CHECK: ClassTemplateSpecializationDecl {{.*}} map
71   // CHECK: OwnerAttr {{.*}}
72 public:
73   typedef __map_iterator<T> iterator;
74 };
75 static_assert(sizeof(map<int>::iterator), ""); // Force instantiation.
76 
77 // Inline namespaces are ignored when checking if
78 // the class lives in the std namespace.
79 inline namespace inlinens {
80 template <typename T>
81 class __unordered_map_iterator {};
82 // CHECK: ClassTemplateDecl {{.*}} __unordered_map_iterator
83 // CHECK: PointerAttr
84 // CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_map_iterator
85 // CHECK: TemplateArgument type 'int'
86 // CHECK: PointerAttr
87 
88 template <typename T>
89 class unordered_map {
90   // CHECK: ClassTemplateDecl {{.*}} unordered_map
91   // CHECK: OwnerAttr {{.*}}
92   // CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_map
93   // CHECK: OwnerAttr {{.*}}
94 public:
95   typedef __unordered_map_iterator<T> iterator;
96 };
97 static_assert(sizeof(unordered_map<int>::iterator), ""); // Force instantiation.
98 } // namespace inlinens
99 
100 // The iterator typedef is a DependentNameType.
101 template <typename T>
102 class __unordered_multimap_iterator {};
103 // CHECK: ClassTemplateDecl {{.*}} __unordered_multimap_iterator
104 // CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_multimap_iterator
105 // CHECK: TemplateArgument type 'int'
106 // CHECK: PointerAttr
107 
108 template <typename T>
109 class __unordered_multimap_base {
110 public:
111   using iterator = __unordered_multimap_iterator<T>;
112 };
113 
114 template <typename T>
115 class unordered_multimap {
116   // CHECK: ClassTemplateDecl {{.*}} unordered_multimap
117   // CHECK: OwnerAttr {{.*}}
118   // CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_multimap
119   // CHECK: OwnerAttr {{.*}}
120 public:
121   using _Mybase = __unordered_multimap_base<T>;
122   using iterator = typename _Mybase::iterator;
123 };
124 static_assert(sizeof(unordered_multimap<int>::iterator), ""); // Force instantiation.
125 
126 // The canonical declaration of the iterator template is not its definition.
127 template <typename T>
128 class __unordered_multiset_iterator;
129 // CHECK: ClassTemplateDecl {{.*}} __unordered_multiset_iterator
130 // CHECK: PointerAttr
131 // CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_multiset_iterator
132 // CHECK: TemplateArgument type 'int'
133 // CHECK: PointerAttr
134 
135 template <typename T>
136 class __unordered_multiset_iterator {
137   // CHECK: ClassTemplateDecl {{.*}} prev {{.*}} __unordered_multiset_iterator
138   // CHECK: PointerAttr
139 };
140 
141 template <typename T>
142 class unordered_multiset {
143   // CHECK: ClassTemplateDecl {{.*}} unordered_multiset
144   // CHECK: OwnerAttr {{.*}}
145   // CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_multiset
146   // CHECK: OwnerAttr {{.*}}
147 public:
148   using iterator = __unordered_multiset_iterator<T>;
149 };
150 
151 static_assert(sizeof(unordered_multiset<int>::iterator), ""); // Force instantiation.
152 
153 // std::list has an implicit gsl::Owner attribute,
154 // but explicit attributes take precedence.
155 template <typename T>
156 class [[gsl::Pointer]] list{};
157 // CHECK: ClassTemplateDecl {{.*}} list
158 // CHECK: PointerAttr {{.*}}
159 // CHECK: ClassTemplateSpecializationDecl {{.*}} list
160 // CHECK: PointerAttr {{.*}}
161 
162 static_assert(sizeof(list<int>), ""); // Force instantiation.
163 
164 // Forward declared template (Owner).
165 template <
166     class CharT,
167     class Traits>
168 class basic_regex;
169 // CHECK: ClassTemplateDecl {{.*}} basic_regex
170 // CHECK: OwnerAttr {{.*}}
171 
172 // Forward declared template (Pointer).
173 template <class T>
174 class reference_wrapper;
175 // CHECK: ClassTemplateDecl {{.*}} reference_wrapper
176 // CHECK: PointerAttr {{.*}}
177 
178 class some_unknown_type;
179 // CHECK: CXXRecordDecl {{.*}} some_unknown_type
180 
181 using size_t = unsigned;
182 inline constexpr size_t dynamic_extent = -1;
183 template <typename _Tp, size_t _Extent = dynamic_extent>
184 class span;
185 // CHECK: CXXRecordDecl {{.*}} span
186 // CHECK: PointerAttr {{.*}}
187 
188 
189 template <typename _Tp>
190 struct span<_Tp, dynamic_extent> {};
191 // CHECK: ClassTemplatePartialSpecializationDecl {{.*}} span
192 // CHECK: PointerAttr {{.*}}
193 } // namespace std
194 
195 namespace user {
196 // If a class is not in the std namespace, we don't infer the attributes.
197 class any {
198 };
199 } // namespace user
200