1// RUN: %clang_cc1 -fsyntax-only -Wunused-local-typedef -verify -std=c++1y %s
2
3struct S {
4  typedef int Foo;  // no diag
5};
6
7namespace N {
8  typedef int Foo;  // no diag
9  typedef int Foo2;  // no diag
10}
11
12template <class T> class Vec {};
13
14typedef int global_foo;  // no diag
15
16void 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
66int printf(char const *, ...);
67
68void 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
83template <class T>
84void 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}
102void 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
110void 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
122auto 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}
136auto x = sneaky();
137decltype(x)::t y;
138
139static 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}
147auto sx = static_sneaky();
148decltype(sx)::t sy;
149
150auto 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
160namespace {
161auto 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}
169auto nsx = nstatic_sneaky();
170decltype(nsx)::t nsy;
171}
172
173// Like sneaky(), but returning pointer to local type
174template<typename T>
175struct remove_reference { typedef T type; };
176template<typename T> struct remove_reference<T&> { typedef T type; };
177auto pointer_sneaky() {
178  struct S {
179    typedef int t;
180    typedef int s;
181  };
182  return (S*)nullptr;
183}
184remove_reference<decltype(*pointer_sneaky())>::type::t py;
185
186// Like sneaky(), but returning templated struct referencing local type.
187template <class T> struct container { int a; T t; };
188auto template_sneaky() {
189  struct S {
190    typedef int t;
191    typedef int s;
192  };
193  return container<S>();
194}
195auto tx = template_sneaky();
196decltype(tx.t)::t ty;
197
198// Like sneaky(), but doing its sneakiness by returning a member function
199// pointer.
200auto sneaky_memfun() {
201  struct S {
202    typedef int type;
203    int n;
204  };
205  return &S::n;
206}
207
208template <class T> void sneaky_memfun_g(int T::*p) {
209  typename T::type X;
210}
211
212void sneaky_memfun_h() {
213  sneaky_memfun_g(sneaky_memfun());
214}
215
216void 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
228void *operator new(__SIZE_TYPE__, void *p) throw() { return p; }
229void 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