Index: lib/Sema/Sema.cpp =================================================================== --- lib/Sema/Sema.cpp +++ lib/Sema/Sema.cpp @@ -470,6 +470,13 @@ return true; if (const FunctionDecl *FD = dyn_cast(D)) { + // If this is a function template, we should remove if it has no + // specializations. + if (FunctionTemplateDecl *Template = FD->getDescribedFunctionTemplate()) { + if (std::distance(Template->spec_begin(), Template->spec_end())) + return true; + } + // UnusedFileScopedDecls stores the first declaration. // The declaration may have become definition so check again. const FunctionDecl *DeclToCheck; Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -1493,6 +1493,10 @@ // 'static inline' functions are defined in headers; don't warn. if (FD->isInlined() && !isMainFileLoc(*this, FD->getLocation())) return false; + // 'static operator' functions are defined in headers; don't warn. + if (FD->isOverloadedOperator() && + !isMainFileLoc(*this, FD->getLocation())) + return false; } if (FD->doesThisDeclarationHaveABody() && @@ -8846,6 +8850,7 @@ if (FunctionTemplate) { if (NewFD->isInvalidDecl()) FunctionTemplate->setInvalidDecl(); + MarkUnusedFileScopedDecl(NewFD); return FunctionTemplate; } } Index: lib/Serialization/ASTReader.cpp =================================================================== --- lib/Serialization/ASTReader.cpp +++ lib/Serialization/ASTReader.cpp @@ -6511,12 +6511,6 @@ return GetDecl(ID); } -template -static void completeRedeclChainForTemplateSpecialization(Decl *D) { - if (auto *TSD = dyn_cast(D)) - TSD->getSpecializedTemplate()->LoadLazySpecializations(); -} - void ASTReader::CompleteRedeclChain(const Decl *D) { if (NumCurrentElementsDeserializing) { // We arrange to not care about the complete redeclaration chain while we're @@ -7136,7 +7130,7 @@ } template -static void +LLVM_DUMP_METHOD static void dumpModuleIDMap(StringRef Name, const ContinuousRangeMap &Map) { Index: test/SemaCXX/warn-unused-filescoped.cpp =================================================================== --- test/SemaCXX/warn-unused-filescoped.cpp +++ test/SemaCXX/warn-unused-filescoped.cpp @@ -32,6 +32,14 @@ inline void bar(int, int) { } }; +namespace test8 { +// Should ignore overloaded operators. +template +struct S {}; +template +static bool operator==(S lhs, S rhs) { } +} + namespace pr19713 { #if __cplusplus >= 201103L static constexpr int constexpr1() { return 1; } @@ -200,6 +208,11 @@ static void func() {} } +namespace test9 { +template +static void completeRedeclChainForTemplateSpecialization() { } // expected-warning {{unused}} +} + namespace pr19713 { #if __cplusplus >= 201103L // FIXME: We should warn on both of these.