[-fms-extensions] Make some exception specification warnings/errors compatible with what cl.exe does

Make clang-cl error when a function definition is missing 'noexcept',
and succeed without warnings when missing '__declspec(nothrow)' or 'throw'.

Fixes pr52860

Differential Revision: https://reviews.llvm.org/D116256
This commit is contained in:
Amy Huang 2021-12-23 15:09:30 -08:00
parent 3a604fdbcd
commit 28d2977ff2
3 changed files with 16 additions and 12 deletions

View File

@ -1695,9 +1695,6 @@ def err_missing_exception_specification : Error<
def ext_missing_exception_specification : ExtWarn<
err_missing_exception_specification.Text>,
InGroup<DiagGroup<"missing-exception-spec">>;
def ext_ms_missing_exception_specification : ExtWarn<
err_missing_exception_specification.Text>,
InGroup<MicrosoftExceptionSpec>;
def err_noexcept_needs_constant_expression : Error<
"argument to noexcept specifier must be a constant expression">;
def err_exception_spec_not_parsed : Error<

View File

@ -391,9 +391,8 @@ bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) {
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 @@ bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) {
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;

View File

@ -2,6 +2,8 @@
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -Wmicrosoft -verify -fms-compatibility -fexceptions -fcxx-exceptions -fms-compatibility-version=19.27
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -Wmicrosoft -verify -fms-compatibility -fexceptions -fcxx-exceptions -fms-compatibility-version=19.00
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -Wmicrosoft -verify -fms-compatibility -fexceptions -fcxx-exceptions -fms-compatibility-version=18.00
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++17 -Wmicrosoft -verify -fms-compatibility -fexceptions -fcxx-exceptions
#if defined(_HAS_CHAR16_T_LANGUAGE_SUPPORT) && _HAS_CHAR16_T_LANGUAGE_SUPPORT
char16_t x;
@ -350,6 +352,7 @@ namespace microsoft_exception_spec {
void foo(); // expected-note {{previous declaration}}
void foo() throw(); // expected-warning {{exception specification in declaration does not match previous declaration}}
#if __cplusplus < 201703L
void r6() throw(...); // expected-note {{previous declaration}}
void r6() throw(int); // expected-warning {{exception specification in declaration does not match previous declaration}}
@ -362,6 +365,7 @@ struct Derived : Base {
virtual void f2() throw(...);
virtual void f3();
};
#endif
class A {
virtual ~A() throw();
@ -377,14 +381,14 @@ class B : public A {
#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 {