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 
f()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 
test()68 void test() {
69   typedef signed long int superint; // no diag
70   printf("%ld", (superint)42);
71 
72   typedef signed long int superint2; // no diag
73   printf("%ld", 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>
template_fun(T 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 }
template_fun_user()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 
typedef_in_nested_name()110 void typedef_in_nested_name() {
111   typedef struct { // expected-warning {{add a tag name}}
112     typedef int Foo; // expected-note {{}}
113   } A; // expected-note {{}}
114   A::Foo adsf;
115 
116   using A2 = struct { // expected-warning {{add a tag name}} expected-note {{this alias declaration}}
117     typedef int Foo; // expected-note {{}}
118   };
119   A2::Foo adsf2;
120 }
121 
sneaky()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 
static_sneaky()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 
sneaky_with_friends()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 {
nstatic_sneaky()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; };
pointer_sneaky()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; };
template_sneaky()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.
sneaky_memfun()200 auto sneaky_memfun() {
201   struct S {
202     typedef int type;
203     int n;
204   };
205   return &S::n;
206 }
207 
sneaky_memfun_g(int T::* p)208 template <class T> void sneaky_memfun_g(int T::*p) {
209   typename T::type X;
210 }
211 
sneaky_memfun_h()212 void sneaky_memfun_h() {
213   sneaky_memfun_g(sneaky_memfun());
214 }
215 
typedefs_in_constructors()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 
operator new(__SIZE_TYPE__,void * p)228 void *operator new(__SIZE_TYPE__, void *p) throw() { return p; }
placement_new_and_delete()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