1 | // RUN: %clang_cc1 -fsyntax-only -Wunused-local-typedef -verify -std=c++1y %s |
2 | |
3 | struct S { |
4 | typedef int Foo; // no diag |
5 | }; |
6 | |
7 | namespace N { |
8 | typedef int Foo; // no diag |
9 | typedef int Foo2; // no diag |
10 | } |
11 | |
12 | template <class T> class Vec {}; |
13 | |
14 | typedef int global_foo; // no diag |
15 | |
16 | void f() { |
17 | typedef int foo0; // expected-warning {{unused typedef 'foo0'}} |
18 | using foo0alias = int ; // expected-warning {{unused type alias 'foo0alias'}} |
19 | |
20 | typedef int foo1 __attribute__((unused)); // no diag |
21 | |
22 | typedef int foo2; |
23 | { |
24 | typedef int foo2; // expected-warning {{unused typedef 'foo2'}} |
25 | } |
26 | typedef foo2 foo3; // expected-warning {{unused typedef 'foo3'}} |
27 | |
28 | typedef int foo2_2; // expected-warning {{unused typedef 'foo2_2'}} |
29 | { |
30 | typedef int foo2_2; |
31 | typedef foo2_2 foo3_2; // expected-warning {{unused typedef 'foo3_2'}} |
32 | } |
33 | |
34 | typedef int foo4; |
35 | foo4 the_thing; |
36 | |
37 | typedef int* foo5; |
38 | typedef foo5* foo6; // no diag |
39 | foo6 *myptr; |
40 | |
41 | struct S2 { |
42 | typedef int Foo; // no diag |
43 | typedef int Foo2; // expected-warning {{unused typedef 'Foo2'}} |
44 | |
45 | struct Deeper { |
46 | typedef int DeepFoo; // expected-warning {{unused typedef 'DeepFoo'}} |
47 | }; |
48 | }; |
49 | |
50 | S2::Foo s2foo; |
51 | |
52 | typedef struct {} foostruct; // expected-warning {{unused typedef 'foostruct'}} |
53 | |
54 | typedef struct {} foostruct2; // no diag |
55 | foostruct2 fs2; |
56 | |
57 | typedef int vecint; // no diag |
58 | Vec<vecint> v; |
59 | |
60 | N::Foo nfoo; |
61 | |
62 | typedef int ConstExprInt; |
63 | static constexpr int a = (ConstExprInt)4; |
64 | } |
65 | |
66 | int printf(char const *, ...); |
67 | |
68 | void test() { |
69 | typedef signed long int superint; // no diag |
70 | printf("%f", (superint) 42); |
71 | |
72 | typedef signed long int superint2; // no diag |
73 | printf("%f", static_cast<superint2>(42)); |
74 | |
75 | #pragma clang diagnostic push |
76 | #pragma clang diagnostic ignored "-Wunused-local-typedef" |
77 | typedef int trungl_bot_was_here; // no diag |
78 | #pragma clang diagnostic pop |
79 | |
80 | typedef int foo; // expected-warning {{unused typedef 'foo'}} |
81 | } |
82 | |
83 | template <class T> |
84 | void template_fun(T t) { |
85 | typedef int foo; // expected-warning {{unused typedef 'foo'}} |
86 | typedef int bar; // no-diag |
87 | bar asdf; |
88 | |
89 | struct S2 { |
90 | typedef int Foo; // no diag |
91 | |
92 | typedef int Foo2; // expected-warning {{unused typedef 'Foo2'}} |
93 | |
94 | typedef int Foo3; // no diag |
95 | }; |
96 | |
97 | typename S2::Foo s2foo; |
98 | typename T::Foo s3foo; |
99 | |
100 | typedef typename S2::Foo3 TTSF; // expected-warning {{unused typedef 'TTSF'}} |
101 | } |
102 | void template_fun_user() { |
103 | struct Local { |
104 | typedef int Foo; // no-diag |
105 | typedef int Bar; // expected-warning {{unused typedef 'Bar'}} |
106 | } p; |
107 | template_fun(p); |
108 | } |
109 | |
110 | void typedef_in_nested_name() { |
111 | typedef struct { |
112 | typedef int Foo; |
113 | } A; |
114 | A::Foo adsf; |
115 | |
116 | using A2 = struct { |
117 | typedef int Foo; |
118 | }; |
119 | A2::Foo adsf2; |
120 | } |
121 | |
122 | auto sneaky() { |
123 | struct S { |
124 | // Local typedefs can be used after the scope they were in has closed: |
125 | typedef int t; |
126 | |
127 | // Even if they aren't, this could be an inline function that could be used |
128 | // in another TU, so this shouldn't warn either: |
129 | typedef int s; |
130 | |
131 | private: |
132 | typedef int p; // expected-warning{{unused typedef 'p'}} |
133 | }; |
134 | return S(); |
135 | } |
136 | auto x = sneaky(); |
137 | decltype(x)::t y; |
138 | |
139 | static auto static_sneaky() { |
140 | struct S { |
141 | typedef int t; |
142 | // This function has internal linkage, so we can warn: |
143 | typedef int s; // expected-warning {{unused typedef 's'}} |
144 | }; |
145 | return S(); |
146 | } |
147 | auto sx = static_sneaky(); |
148 | decltype(sx)::t sy; |
149 | |
150 | auto sneaky_with_friends() { |
151 | struct S { |
152 | private: |
153 | friend class G; |
154 | // Can't warn if we have friends: |
155 | typedef int p; |
156 | }; |
157 | return S(); |
158 | } |
159 | |
160 | namespace { |
161 | auto nstatic_sneaky() { |
162 | struct S { |
163 | typedef int t; |
164 | // This function has internal linkage, so we can warn: |
165 | typedef int s; // expected-warning {{unused typedef 's'}} |
166 | }; |
167 | return S(); |
168 | } |
169 | auto nsx = nstatic_sneaky(); |
170 | decltype(nsx)::t nsy; |
171 | } |
172 | |
173 | // Like sneaky(), but returning pointer to local type |
174 | template<typename T> |
175 | struct remove_reference { typedef T type; }; |
176 | template<typename T> struct remove_reference<T&> { typedef T type; }; |
177 | auto pointer_sneaky() { |
178 | struct S { |
179 | typedef int t; |
180 | typedef int s; |
181 | }; |
182 | return (S*)nullptr; |
183 | } |
184 | remove_reference<decltype(*pointer_sneaky())>::type::t py; |
185 | |
186 | // Like sneaky(), but returning templated struct referencing local type. |
187 | template <class T> struct container { int a; T t; }; |
188 | auto template_sneaky() { |
189 | struct S { |
190 | typedef int t; |
191 | typedef int s; |
192 | }; |
193 | return container<S>(); |
194 | } |
195 | auto tx = template_sneaky(); |
196 | decltype(tx.t)::t ty; |
197 | |
198 | // Like sneaky(), but doing its sneakiness by returning a member function |
199 | // pointer. |
200 | auto sneaky_memfun() { |
201 | struct S { |
202 | typedef int type; |
203 | int n; |
204 | }; |
205 | return &S::n; |
206 | } |
207 | |
208 | template <class T> void sneaky_memfun_g(int T::*p) { |
209 | typename T::type X; |
210 | } |
211 | |
212 | void sneaky_memfun_h() { |
213 | sneaky_memfun_g(sneaky_memfun()); |
214 | } |
215 | |
216 | void typedefs_in_constructors() { |
217 | struct A {}; |
218 | struct B : public A { |
219 | // Neither of these two should warn: |
220 | typedef A INHERITED; |
221 | B() : INHERITED() {} |
222 | |
223 | typedef B SELF; |
224 | B(int) : SELF() {} |
225 | }; |
226 | } |
227 | |
228 | void *operator new(__SIZE_TYPE__, void *p) throw() { return p; } |
229 | void placement_new_and_delete() { |
230 | struct MyStruct { }; |
231 | char memory[sizeof(MyStruct)]; |
232 | void *p = memory; |
233 | |
234 | typedef MyStruct A_t1; |
235 | MyStruct *a = new (p) A_t1(); |
236 | |
237 | typedef MyStruct A_t2; |
238 | a->~A_t2(); |
239 | } |
240 | |
241 | // This should not disable any warnings: |
242 | #pragma clang diagnostic ignored "-Wunused-local-typedef" |
243 | |