[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