xref: /llvm-project/clang/test/SemaCXX/attr-gsl-owner-pointer-std.cpp (revision 966eea91ad94e38a3654f154d2d5ad28ea5deb9d)
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 // If std::container::iterator is a using declaration, attributes are inferred
31 // for the underlying class.
32 template <typename T>
33 class __set_iterator {};
34 // CHECK: ClassTemplateDecl {{.*}} __set_iterator
35 // CHECK: PointerAttr
36 // CHECK: ClassTemplateSpecializationDecl {{.*}} __set_iterator
37 // CHECK: TemplateArgument type 'int'
38 // CHECK: PointerAttr
39 
40 template <typename T>
41 class set {
42   // CHECK: ClassTemplateDecl {{.*}} set
43   // CHECK: OwnerAttr {{.*}}
44   // CHECK: ClassTemplateSpecializationDecl {{.*}} set
45   // CHECK: OwnerAttr {{.*}}
46 public:
47   using iterator = __set_iterator<T>;
48 };
49 static_assert(sizeof(set<int>::iterator), ""); // Force instantiation.
50 
51 // If std::container::iterator is a typedef, attributes are inferred for the
52 // underlying class.
53 template <typename T>
54 class __map_iterator {};
55 // CHECK: ClassTemplateDecl {{.*}} __map_iterator
56 // CHECK: PointerAttr
57 // CHECK: ClassTemplateSpecializationDecl {{.*}} __map_iterator
58 // CHECK: TemplateArgument type 'int'
59 // CHECK: PointerAttr
60 
61 template <typename T>
62 class map {
63   // CHECK: ClassTemplateDecl {{.*}} map
64   // CHECK: OwnerAttr {{.*}}
65   // CHECK: ClassTemplateSpecializationDecl {{.*}} map
66   // CHECK: OwnerAttr {{.*}}
67 public:
68   typedef __map_iterator<T> iterator;
69 };
70 static_assert(sizeof(map<int>::iterator), ""); // Force instantiation.
71 
72 // Inline namespaces are ignored when checking if
73 // the class lives in the std namespace.
74 inline namespace inlinens {
75 template <typename T>
76 class __unordered_map_iterator {};
77 // CHECK: ClassTemplateDecl {{.*}} __unordered_map_iterator
78 // CHECK: PointerAttr
79 // CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_map_iterator
80 // CHECK: TemplateArgument type 'int'
81 // CHECK: PointerAttr
82 
83 template <typename T>
84 class unordered_map {
85   // CHECK: ClassTemplateDecl {{.*}} unordered_map
86   // CHECK: OwnerAttr {{.*}}
87   // CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_map
88   // CHECK: OwnerAttr {{.*}}
89 public:
90   typedef __unordered_map_iterator<T> iterator;
91 };
92 static_assert(sizeof(unordered_map<int>::iterator), ""); // Force instantiation.
93 } // namespace inlinens
94 
95 // std::list has an implicit gsl::Owner attribute,
96 // but explicit attributes take precedence.
97 template <typename T>
98 class [[gsl::Pointer]] list{};
99 // CHECK: ClassTemplateDecl {{.*}} list
100 // CHECK: PointerAttr {{.*}}
101 // CHECK: ClassTemplateSpecializationDecl {{.*}} list
102 // CHECK: PointerAttr {{.*}}
103 
104 static_assert(sizeof(list<int>), ""); // Force instantiation.
105 
106 // Forward declared template (Owner).
107 template <
108     class CharT,
109     class Traits>
110 class basic_regex;
111 // CHECK: ClassTemplateDecl {{.*}} basic_regex
112 // CHECK: OwnerAttr {{.*}}
113 
114 // Forward declared template (Pointer).
115 template <class T>
116 class reference_wrapper;
117 // CHECK: ClassTemplateDecl {{.*}} reference_wrapper
118 // CHECK: PointerAttr {{.*}}
119 
120 class some_unknown_type;
121 // CHECK: CXXRecordDecl {{.*}} some_unknown_type
122 
123 } // namespace std
124 
125 namespace user {
126 // If a class is not in the std namespace, we don't infer the attributes.
127 class any {
128 };
129 } // namespace user
130