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 @@ -1695,9 +1695,6 @@ def ext_missing_exception_specification : ExtWarn< err_missing_exception_specification.Text>, InGroup>; -def ext_ms_missing_exception_specification : ExtWarn< - err_missing_exception_specification.Text>, - InGroup; def err_noexcept_needs_constant_expression : Error< "argument to noexcept specifier must be a constant expression">; def err_exception_spec_not_parsed : Error< diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -391,9 +391,8 @@ NewProto->getExtProtoInfo().withExceptionSpec(ESI))); } - if (getLangOpts().MSVCCompat && ESI.Type != EST_DependentNoexcept) { - // Allow missing exception specifications in redeclarations as an extension. - DiagID = diag::ext_ms_missing_exception_specification; + if (getLangOpts().MSVCCompat && isDynamicExceptionSpec(ESI.Type)) { + DiagID = diag::ext_missing_exception_specification; ReturnValueOnError = false; } else if (New->isReplaceableGlobalAllocationFunction() && ESI.Type != EST_DependentNoexcept) { @@ -402,6 +401,10 @@ DiagID = diag::ext_missing_exception_specification; ReturnValueOnError = false; } else if (ESI.Type == EST_NoThrow) { + // Don't emit any warning for missing 'nothrow' in MSVC. + if (getLangOpts().MSVCCompat) { + return false; + } // Allow missing attribute 'nothrow' in redeclarations, since this is a very // common omission. DiagID = diag::ext_missing_exception_specification; diff --git a/clang/test/SemaCXX/MicrosoftCompatibility.cpp b/clang/test/SemaCXX/MicrosoftCompatibility.cpp --- a/clang/test/SemaCXX/MicrosoftCompatibility.cpp +++ b/clang/test/SemaCXX/MicrosoftCompatibility.cpp @@ -377,14 +377,14 @@ #endif }; -} +void f4() throw(); // expected-note {{previous declaration is here}} +void f4() {} // expected-warning {{'f4' is missing exception specification 'throw()'}} -namespace PR25265 { -struct S { - int fn() throw(); // expected-note {{previous declaration is here}} -}; +__declspec(nothrow) void f5(); +void f5() {} -int S::fn() { return 0; } // expected-warning {{is missing exception specification}} +void f6() noexcept; // expected-note {{previous declaration is here}} +void f6() {} // expected-error {{'f6' is missing exception specification 'noexcept'}} } namespace PR43265 {