[PATCH] Windows: Don't warn when making large unsigned enum values signed

Reid Kleckner rnk at google.com
Fri Sep 20 16:50:44 PDT 2013


Hi rsmith,

Introduces a new warning flag -Wmicrosoft-signed-enums to cover this
which is off by default.

This avoids many warnings across clang during a self-host with
-fms-compatibility on constructs like 'enum { ~0U }'.  Enums in MSVC
always use 'int' as the underlying type, unless you explicitly specify
the integral type.

http://llvm-reviews.chandlerc.com/D1736

Files:
  include/clang/Basic/DiagnosticGroups.td
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDecl.cpp
  test/Sema/MicrosoftCompatibility.c

Index: include/clang/Basic/DiagnosticGroups.td
===================================================================
--- include/clang/Basic/DiagnosticGroups.td
+++ include/clang/Basic/DiagnosticGroups.td
@@ -569,6 +569,7 @@
 
 // A warning group for warnings about Microsoft extensions.
 def Microsoft : DiagGroup<"microsoft">;
+def MicrosoftSignedEnums : DiagGroup<"microsoft-signed-enums">;
 
 def ObjCNonUnifiedException : DiagGroup<"objc-nonunified-exceptions">;
 
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -1570,6 +1570,9 @@
 def ext_enumerator_too_large : ExtWarn<
   "enumerator value is not representable in the underlying type %0">,
   InGroup<Microsoft>;
+def ext_enumerator_sign_mismatch : ExtWarn<
+  "enumerator value converted to underlying type %0 with opposite sign">,
+  InGroup<MicrosoftSignedEnums>, DefaultIgnore;
 def err_enumerator_wrapped : Error<
   "enumerator value %0 is not representable in the underlying type %1">;
 def err_enum_redeclare_type_mismatch : Error<
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -12082,7 +12082,11 @@
           // expression checking.
           if (!isRepresentableIntegerValue(Context, EnumVal, EltTy)) {
             if (getLangOpts().MicrosoftMode) {
-              Diag(IdLoc, diag::ext_enumerator_too_large) << EltTy;
+              QualType UEltTy = Context.getCorrespondingUnsignedType(EltTy);
+              if (isRepresentableIntegerValue(Context, EnumVal, UEltTy))
+                Diag(IdLoc, diag::ext_enumerator_sign_mismatch) << EltTy;
+              else
+                Diag(IdLoc, diag::ext_enumerator_too_large) << EltTy;
               Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take();
             } else
               Diag(IdLoc, diag::err_enumerator_too_large) << EltTy;
Index: test/Sema/MicrosoftCompatibility.c
===================================================================
--- test/Sema/MicrosoftCompatibility.c
+++ test/Sema/MicrosoftCompatibility.c
@@ -1,14 +1,20 @@
 // RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-compatibility
+// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -Wmicrosoft-signed-enums -DWSIGNED_ENUMS -verify -fms-compatibility
 
 enum ENUM1; // expected-warning {{forward references to 'enum' types are a Microsoft extension}}
 enum ENUM1 var1 = 3;
 enum ENUM1* var2 = 0;
 
 
 enum ENUM2 {
   ENUM2_a = (enum ENUM2) 4,
-  ENUM2_b = 0x9FFFFFFF, // expected-warning {{enumerator value is not representable in the underlying type 'int'}}
-  ENUM2_c = 0x100000000 // expected-warning {{enumerator value is not representable in the underlying type 'int'}}
+#ifdef WSIGNED_ENUMS
+  // expected-warning at +3 {{enumerator value converted to underlying type 'int' with opposite sign}}
+  // expected-warning at +3 {{enumerator value converted to underlying type 'int' with opposite sign}}
+#endif
+  ENUM2_b = ~0U,
+  ENUM2_c = 0x9FFFFFFF,
+  ENUM2_d = 0x100000000 // expected-warning {{enumerator value is not representable in the underlying type 'int'}}
 };
 
 __declspec(noreturn) void f6( void ) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1736.1.patch
Type: text/x-patch
Size: 3341 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130920/d663c2e2/attachment.bin>


More information about the cfe-commits mailing list