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