// RUN: %clang_cc1 -fsyntax-only -Wunused-local-typedef -verify -std=c++1y %s struct S { typedef int Foo; // no diag }; namespace N { typedef int Foo; // no diag typedef int Foo2; // no diag } template class Vec {}; typedef int global_foo; // no diag void f() { typedef int foo0; // expected-warning {{unused typedef 'foo0'}} using foo0alias = int ; // expected-warning {{unused type alias 'foo0alias'}} typedef int foo1 __attribute__((unused)); // no diag typedef int foo2; { typedef int foo2; // expected-warning {{unused typedef 'foo2'}} } typedef foo2 foo3; // expected-warning {{unused typedef 'foo3'}} typedef int foo2_2; // expected-warning {{unused typedef 'foo2_2'}} { typedef int foo2_2; typedef foo2_2 foo3_2; // expected-warning {{unused typedef 'foo3_2'}} } typedef int foo4; foo4 the_thing; typedef int* foo5; typedef foo5* foo6; // no diag foo6 *myptr; struct S2 { typedef int Foo; // no diag typedef int Foo2; // expected-warning {{unused typedef 'Foo2'}} struct Deeper { typedef int DeepFoo; // expected-warning {{unused typedef 'DeepFoo'}} }; }; S2::Foo s2foo; typedef struct {} foostruct; // expected-warning {{unused typedef 'foostruct'}} typedef struct {} foostruct2; // no diag foostruct2 fs2; typedef int vecint; // no diag Vec v; N::Foo nfoo; typedef int ConstExprInt; static constexpr int a = (ConstExprInt)4; } int printf(char const *, ...); void test() { typedef signed long int superint; // no diag printf("%f", (superint) 42); typedef signed long int superint2; // no diag printf("%f", static_cast(42)); #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-local-typedef" typedef int trungl_bot_was_here; // no diag #pragma clang diagnostic pop typedef int foo; // expected-warning {{unused typedef 'foo'}} } template void template_fun(T t) { typedef int foo; // expected-warning {{unused typedef 'foo'}} typedef int bar; // no-diag bar asdf; struct S2 { typedef int Foo; // no diag typedef int Foo2; // expected-warning {{unused typedef 'Foo2'}} typedef int Foo3; // no diag }; typename S2::Foo s2foo; typename T::Foo s3foo; typedef typename S2::Foo3 TTSF; // expected-warning {{unused typedef 'TTSF'}} } void template_fun_user() { struct Local { typedef int Foo; // no-diag typedef int Bar; // expected-warning {{unused typedef 'Bar'}} } p; template_fun(p); } void typedef_in_nested_name() { typedef struct { typedef int Foo; } A; A::Foo adsf; using A2 = struct { typedef int Foo; }; A2::Foo adsf2; } auto sneaky() { struct S { // Local typedefs can be used after the scope they were in has closed: typedef int t; // Even if they aren't, this could be an inline function that could be used // in another TU, so this shouldn't warn either: typedef int s; private: typedef int p; // expected-warning{{unused typedef 'p'}} }; return S(); } auto x = sneaky(); decltype(x)::t y; static auto static_sneaky() { struct S { typedef int t; // This function has internal linkage, so we can warn: typedef int s; // expected-warning {{unused typedef 's'}} }; return S(); } auto sx = static_sneaky(); decltype(sx)::t sy; auto sneaky_with_friends() { struct S { private: friend class G; // Can't warn if we have friends: typedef int p; }; return S(); } namespace { auto nstatic_sneaky() { struct S { typedef int t; // This function has internal linkage, so we can warn: typedef int s; // expected-warning {{unused typedef 's'}} }; return S(); } auto nsx = nstatic_sneaky(); decltype(nsx)::t nsy; } // Like sneaky(), but returning pointer to local type template struct remove_reference { typedef T type; }; template struct remove_reference { typedef T type; }; auto pointer_sneaky() { struct S { typedef int t; typedef int s; }; return (S*)nullptr; } remove_reference::type::t py; // Like sneaky(), but returning templated struct referencing local type. template struct container { int a; T t; }; auto template_sneaky() { struct S { typedef int t; typedef int s; }; return container(); } auto tx = template_sneaky(); decltype(tx.t)::t ty; // Like sneaky(), but doing its sneakiness by returning a member function // pointer. auto sneaky_memfun() { struct S { typedef int type; int n; }; return &S::n; } template void sneaky_memfun_g(int T::*p) { typename T::type X; } void sneaky_memfun_h() { sneaky_memfun_g(sneaky_memfun()); } void typedefs_in_constructors() { struct A {}; struct B : public A { // Neither of these two should warn: typedef A INHERITED; B() : INHERITED() {} typedef B SELF; B(int) : SELF() {} }; } void *operator new(__SIZE_TYPE__, void *p) throw() { return p; } void placement_new_and_delete() { struct MyStruct { }; char memory[sizeof(MyStruct)]; void *p = memory; typedef MyStruct A_t1; MyStruct *a = new (p) A_t1(); typedef MyStruct A_t2; a->~A_t2(); } // This should not disable any warnings: #pragma clang diagnostic ignored "-Wunused-local-typedef"