diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1794,16 +1794,19 @@ // Except for labels, we only care about unused decls that are local to // functions. - bool WithinFunction = D->getDeclContext()->isFunctionOrMethod(); - if (const auto *R = dyn_cast(D->getDeclContext())) - // For dependent types, the diagnostic is deferred. - WithinFunction = - WithinFunction || (R->isLocalClass() && !R->isDependentType()); + auto *Context = D->getDeclContext(); + bool WithinFunction = Context->isFunctionOrMethod(); + if (const auto *R = dyn_cast(Context)) + WithinFunction = WithinFunction || R->isLocalClass(); if (!WithinFunction) return false; - if (isa(D)) + if (const auto *TD = dyn_cast(D)) { + // Defer warnings for typedefs within a dependent context. + if (Context->isDependentContext()) + return false; return true; + } // White-list anything that isn't a local variable. if (!isa(D) || isa(D) || isa(D)) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -955,6 +955,14 @@ Typedef->setAccess(D->getAccess()); Typedef->setReferenced(D->isReferenced()); + // Diagnose unused local typedefs here since diagnostics for typedefs + // in a dependent context were deffered). + bool ShouldDiagnoseUnused = Typedef->getDeclContext()->isFunctionOrMethod(); + if (const auto *R = dyn_cast(Typedef->getDeclContext())) + ShouldDiagnoseUnused = ShouldDiagnoseUnused || R->isLocalClass(); + if (!Typedef->isInvalidDecl() && ShouldDiagnoseUnused) + SemaRef.DiagnoseUnusedDecl(Typedef); + return Typedef; } @@ -1907,8 +1915,6 @@ LocalInstantiations.perform(); } - SemaRef.DiagnoseUnusedNestedTypedefs(Record); - if (IsInjectedClassName) assert(Record->isInjectedClassName() && "Broken injected-class-name"); diff --git a/clang/test/SemaCXX/warn-unused-local-typedef.cpp b/clang/test/SemaCXX/warn-unused-local-typedef.cpp --- a/clang/test/SemaCXX/warn-unused-local-typedef.cpp +++ b/clang/test/SemaCXX/warn-unused-local-typedef.cpp @@ -255,5 +255,20 @@ } } // TypedefInLocalClassOfTemplateClassMember +namespace TypedefInDependentQualifiedIdentifier { +struct A { void f() const {} }; + +template +void handler(const T &item) { + using a_type_t = A; // no-diag + using b_type_t = A; // expected-warning {{unused type alias 'b_type_t'}} + item.a_type_t::f(); +} + +void foo() { + handler(A()); +} +} // TypedefInDependentQualifiedIdentifier + // This should not disable any warnings: #pragma clang diagnostic ignored "-Wunused-local-typedef"