r371581 - Emit -Wmicrosoft-enum-value warning instead of error in MS ABI

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 10 18:01:06 PDT 2019


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




More information about the cfe-commits mailing list