From 3940f412bff449818c5f297abbb5bdb1b756de3b Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Wed, 8 May 2019 13:24:36 +0000 Subject: [PATCH] Allow 'static' storage specifier on an out-of-line class member template declaration in MSVCCompat mode. Patch by Soumi Manna. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@360250 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 7 +++++-- test/SemaCXX/warn-static-outside-class-definition.cpp | 11 +++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 8fd6ab860a..3ac5a3749d 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -8673,9 +8673,12 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // member function definition. // MSVC permits the use of a 'static' storage specifier on an out-of-line - // member function template declaration, warn about this. + // member function template declaration and class member template + // declaration (MSVC versions before 2015), warn about this. Diag(D.getDeclSpec().getStorageClassSpecLoc(), - NewFD->getDescribedFunctionTemplate() && getLangOpts().MSVCCompat + ((!getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015) && + cast(DC)->getDescribedClassTemplate()) || + (getLangOpts().MSVCCompat && NewFD->getDescribedFunctionTemplate())) ? diag::ext_static_out_of_line : diag::err_static_out_of_line) << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc()); } diff --git a/test/SemaCXX/warn-static-outside-class-definition.cpp b/test/SemaCXX/warn-static-outside-class-definition.cpp index 5235d35cb1..9a3f96b772 100644 --- a/test/SemaCXX/warn-static-outside-class-definition.cpp +++ b/test/SemaCXX/warn-static-outside-class-definition.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fms-compatibility -fsyntax-only -verify %s +// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -fms-compatibility-version=12.0 -verify %s struct C { template static int foo(T); @@ -9,3 +10,13 @@ template static int C::foo(T) { return 0; } +template struct S { + void f(); +}; + +template static void S::f() {} +#if _MSC_VER >= 1900 + //expected-error@-2 {{'static' can only be specified inside the class definition}} +#else + //expected-warning@-4 {{'static' can only be specified inside the class definition}} +#endif -- 2.40.0