Author: rnk Date: Tue Sep 10 18:01:06 2019 New Revision: 371581 URL: http://llvm.org/viewvc/llvm-project?rev=371581&view=rev Log: Emit -Wmicrosoft-enum-value warning instead of error in MS ABI
Summary: The first NFC change is to replace a getCXXABI().isMicrosoft() check with getTriple().isWindowsMSVCEnvironment(). This code takes effect in non-C++ compilations, so it doesn't make sense to check the C++ ABI. In the MS ABI, enums are always considered to be "complete" because the underlying type of an unfixed enum will always be 'int'. This behavior was moved from -fms-compatibility to MS ABI back in r249656. The second change is functional, and it downgrades an error to a warning when the MS ABI is used rather than only under -fms-compatibility. The reasoning is that it's unreasonable for the following code to reject the following code for all MS ABI targets with -fno-ms-compatibility: enum Foo { Foo_Val = 0xDEADBEEF }; This is valid code for any other target, but in the MS ABI, Foo_Val just happens to be negative. With this change, clang emits a -Wmicrosoft-enum-value warning on this code, but compiles it without error. Fixes PR38478 Reviewers: hans, rsmith, STL_MSFT Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D67304 Modified: cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/Sema/MicrosoftCompatibility.c Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=371581&r1=371580&r2=371581&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Sep 10 18:01:06 2019 @@ -14723,7 +14723,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned UPPC_FixedUnderlyingType)) EnumUnderlying = Context.IntTy.getTypePtr(); - } else if (Context.getTargetInfo().getCXXABI().isMicrosoft()) { + } else if (Context.getTargetInfo().getTriple().isWindowsMSVCEnvironment()) { // For MSVC ABI compatibility, unfixed enums must use an underlying type // of 'int'. However, if this is an unfixed forward declaration, don't set // the underlying type unless the user enables -fms-compatibility. This @@ -16850,8 +16850,7 @@ EnumConstantDecl *Sema::CheckEnumConstan if (Enum->isDependentType() || Val->isTypeDependent()) EltTy = Context.DependentTy; else { - if (getLangOpts().CPlusPlus11 && Enum->isFixed() && - !getLangOpts().MSVCCompat) { + if (getLangOpts().CPlusPlus11 && Enum->isFixed()) { // C++11 [dcl.enum]p5: If the underlying type is fixed, [...] the // constant-expression in the enumerator-definition shall be a converted // constant expression of the underlying type. @@ -16876,15 +16875,19 @@ EnumConstantDecl *Sema::CheckEnumConstan // we perform a non-narrowing conversion as part of converted constant // expression checking. if (!isRepresentableIntegerValue(Context, EnumVal, EltTy)) { - if (getLangOpts().MSVCCompat) { + if (Context.getTargetInfo() + .getTriple() + .isWindowsMSVCEnvironment()) { Diag(IdLoc, diag::ext_enumerator_too_large) << EltTy; - Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).get(); - } else + } else { Diag(IdLoc, diag::err_enumerator_too_large) << EltTy; - } else - Val = ImpCastExprToType(Val, EltTy, - EltTy->isBooleanType() ? - CK_IntegralToBoolean : CK_IntegralCast) + } + } + + // Cast to the underlying type. + Val = ImpCastExprToType(Val, EltTy, + EltTy->isBooleanType() ? CK_IntegralToBoolean + : CK_IntegralCast) .get(); } else if (getLangOpts().CPlusPlus) { // C++11 [dcl.enum]p5: Modified: cfe/trunk/test/Sema/MicrosoftCompatibility.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/MicrosoftCompatibility.c?rev=371581&r1=371580&r2=371581&view=diff ============================================================================== --- cfe/trunk/test/Sema/MicrosoftCompatibility.c (original) +++ cfe/trunk/test/Sema/MicrosoftCompatibility.c Tue Sep 10 18:01:06 2019 @@ -1,10 +1,18 @@ -// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-compatibility -triple i686-pc-win32 +// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-compatibility -DMSVCCOMPAT -triple i686-pc-win32 +// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-extensions -triple i686-pc-win32 +#ifdef MSVCCOMPAT enum ENUM1; // expected-warning {{forward references to 'enum' types are a Microsoft extension}} enum ENUM1 var1 = 3; enum ENUM1* var2 = 0; +#else +enum ENUM1; // expected-note {{forward declaration of}} +enum ENUM1 var1 = 3; // expected-error {{variable has incomplete type 'enum ENUM1'}} +enum ENUM1* var2 = 0; +#endif +// FIXME: The rest of this seems to be controlled by -fms-extensions. Move it. enum ENUM2 { ENUM2_a = (enum ENUM2) 4, ENUM2_b = 0x9FFFFFFF, // expected-warning {{enumerator value is not representable in the underlying type 'int'}} @@ -22,4 +30,8 @@ struct __declspec(appdomain) S3 {}; /* e __declspec(__noreturn__) void f7(void); /* expected-warning {{__declspec attribute '__noreturn__' is not supported}} */ +#ifdef MSVCCOMPAT size_t x; +#else +size_t x; // expected-error {{unknown type name 'size_t'}} +#endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits