diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -360,8 +360,9 @@ "%select{function|variable}0 %1 is not needed and will not be emitted">, InGroup, DefaultIgnore; def warn_unneeded_static_internal_decl : Warning< - "'static' function %0 declared in header file " - "should be declared 'static inline'">, + "function %0 declared in header file should " + "%select{be declared 'inline' instead of|not be declared}1 " + "%select{in an anonymous namespace|'static'}2">, InGroup, DefaultIgnore; def warn_unneeded_member_function : Warning< "member function %0 is not needed and will not be emitted">, diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1211,13 +1211,12 @@ Diag(DiagD->getLocation(), diag::warn_unneeded_member_function) << DiagD; else { - if (FD->getStorageClass() == SC_Static && - !FD->isInlineSpecified() && - !SourceMgr.isInMainFile( - SourceMgr.getExpansionLoc(FD->getLocation()))) + if (!SourceMgr.isInMainFile( + SourceMgr.getExpansionLoc(FD->getLocation()))) Diag(DiagD->getLocation(), diag::warn_unneeded_static_internal_decl) - << DiagD; + << DiagD << FD->isInlineSpecified() + << (FD->getStorageClass() == SC_Static); else Diag(DiagD->getLocation(), diag::warn_unneeded_internal_decl) << /*function*/ 0 << DiagD; 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 @@ -1697,10 +1697,6 @@ if (const CXXMethodDecl *MD = dyn_cast(FD)) { if (MD->isVirtual() || IsDisallowedCopyOrAssign(MD)) return false; - } else { - // 'static inline' functions are defined in headers; don't warn. - if (FD->isInlined() && !isMainFileLoc(*this, FD->getLocation())) - return false; } if (FD->doesThisDeclarationHaveABody() && diff --git a/clang/test/SemaCXX/warn-static-function-inheader.h b/clang/test/SemaCXX/warn-static-function-inheader.h --- a/clang/test/SemaCXX/warn-static-function-inheader.h +++ b/clang/test/SemaCXX/warn-static-function-inheader.h @@ -1,3 +1,13 @@ -static void thing(void) { // expected-warning {{'static' function 'thing' declared in header file should be declared 'static inline'}} +static void thing(void) { // expected-warning {{function 'thing' declared in header file should be declared 'inline' instead of 'static'}} } +static inline void inline_thing(void) { // expected-warning {{function 'inline_thing' declared in header file should not be declared 'static'}} +} + +namespace { +void anon_thing(void) { // expected-warning {{function 'anon_thing' declared in header file should be declared 'inline' instead of in an anonymous namespace}} +} + +inline void anon_inline_thing(void) { // expected-warning {{function 'anon_inline_thing' declared in header file should not be declared in an anonymous namespace}} +} +} // namespace diff --git a/clang/test/SemaCXX/warn-static-function-inheader.cpp b/clang/test/SemaCXX/warn-static-function-inheader.cpp --- a/clang/test/SemaCXX/warn-static-function-inheader.cpp +++ b/clang/test/SemaCXX/warn-static-function-inheader.cpp @@ -7,6 +7,9 @@ template void foo(void) { - thing(); - another(); + thing(); + inline_thing(); + anon_thing(); + anon_inline_thing(); + another(); } diff --git a/clang/test/SemaCXX/warn-unused-filescoped.cpp b/clang/test/SemaCXX/warn-unused-filescoped.cpp --- a/clang/test/SemaCXX/warn-unused-filescoped.cpp +++ b/clang/test/SemaCXX/warn-unused-filescoped.cpp @@ -5,26 +5,26 @@ #ifdef HEADER static void headerstatic() {} // expected-warning{{unused function 'headerstatic'}} -static inline void headerstaticinline() {} +static inline void headerstaticinline() {} // expected-warning{{unused function 'headerstaticinline'}} namespace { void headeranon() {} // expected-warning{{unused function 'headeranon'}} -inline void headerinlineanon() {} +inline void headerinlineanon() {} // expected-warning{{unused function 'headerinlineanon'}} } namespace test7 { template - static inline void foo(T) { } + static inline void foo(T) { } // expected-warning{{unused function template 'foo'}} - // This should not emit an unused-function warning since it inherits + // This should emit an unused-function warning since it inherits // the static storage type from the base template. template<> - inline void foo(int) { } + inline void foo(int) { } // expected-warning{{unused function 'foo'}} // Partial specialization template - static inline void bar(T, U) { } + static inline void bar(T, U) { } // expected-warning{{unused function template 'bar'}} template inline void bar(int, U) { } @@ -35,7 +35,7 @@ namespace pr19713 { #if __cplusplus >= 201103L - static constexpr int constexpr1() { return 1; } + static constexpr int constexpr1() { return 1; } // expected-warning{{unused function 'constexpr1'}} constexpr int constexpr2() { return 2; } #endif }