<div dir="ltr">Let's try the other Richard, since Mr. Smith is in Chicago.</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Sep 20, 2013 at 4:50 PM, Reid Kleckner <span dir="ltr"><<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi rsmith,<br>
<br>
Introduces a new warning flag -Wmicrosoft-signed-enums to cover this<br>
which is off by default.<br>
<br>
This avoids many warnings across clang during a self-host with<br>
-fms-compatibility on constructs like 'enum { ~0U }'. Enums in MSVC<br>
always use 'int' as the underlying type, unless you explicitly specify<br>
the integral type.<br>
<br>
<a href="http://llvm-reviews.chandlerc.com/D1736" target="_blank">http://llvm-reviews.chandlerc.com/D1736</a><br>
<br>
Files:<br>
include/clang/Basic/DiagnosticGroups.td<br>
include/clang/Basic/DiagnosticSemaKinds.td<br>
lib/Sema/SemaDecl.cpp<br>
test/Sema/MicrosoftCompatibility.c<br>
<br>
Index: include/clang/Basic/DiagnosticGroups.td<br>
===================================================================<br>
--- include/clang/Basic/DiagnosticGroups.td<br>
+++ include/clang/Basic/DiagnosticGroups.td<br>
@@ -569,6 +569,7 @@<br>
<br>
// A warning group for warnings about Microsoft extensions.<br>
def Microsoft : DiagGroup<"microsoft">;<br>
+def MicrosoftSignedEnums : DiagGroup<"microsoft-signed-enums">;<br>
<br>
def ObjCNonUnifiedException : DiagGroup<"objc-nonunified-exceptions">;<br>
<br>
Index: include/clang/Basic/DiagnosticSemaKinds.td<br>
===================================================================<br>
--- include/clang/Basic/DiagnosticSemaKinds.td<br>
+++ include/clang/Basic/DiagnosticSemaKinds.td<br>
@@ -1570,6 +1570,9 @@<br>
def ext_enumerator_too_large : ExtWarn<<br>
"enumerator value is not representable in the underlying type %0">,<br>
InGroup<Microsoft>;<br>
+def ext_enumerator_sign_mismatch : ExtWarn<<br>
+ "enumerator value converted to underlying type %0 with opposite sign">,<br>
+ InGroup<MicrosoftSignedEnums>, DefaultIgnore;<br>
def err_enumerator_wrapped : Error<<br>
"enumerator value %0 is not representable in the underlying type %1">;<br>
def err_enum_redeclare_type_mismatch : Error<<br>
Index: lib/Sema/SemaDecl.cpp<br>
===================================================================<br>
--- lib/Sema/SemaDecl.cpp<br>
+++ lib/Sema/SemaDecl.cpp<br>
@@ -12082,7 +12082,11 @@<br>
// expression checking.<br>
if (!isRepresentableIntegerValue(Context, EnumVal, EltTy)) {<br>
if (getLangOpts().MicrosoftMode) {<br>
- Diag(IdLoc, diag::ext_enumerator_too_large) << EltTy;<br>
+ QualType UEltTy = Context.getCorrespondingUnsignedType(EltTy);<br>
+ if (isRepresentableIntegerValue(Context, EnumVal, UEltTy))<br>
+ Diag(IdLoc, diag::ext_enumerator_sign_mismatch) << EltTy;<br>
+ else<br>
+ Diag(IdLoc, diag::ext_enumerator_too_large) << EltTy;<br>
Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take();<br>
} else<br>
Diag(IdLoc, diag::err_enumerator_too_large) << EltTy;<br>
Index: test/Sema/MicrosoftCompatibility.c<br>
===================================================================<br>
--- test/Sema/MicrosoftCompatibility.c<br>
+++ test/Sema/MicrosoftCompatibility.c<br>
@@ -1,14 +1,20 @@<br>
// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-compatibility<br>
+// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -Wmicrosoft-signed-enums -DWSIGNED_ENUMS -verify -fms-compatibility<br>
<br>
enum ENUM1; // expected-warning {{forward references to 'enum' types are a Microsoft extension}}<br>
enum ENUM1 var1 = 3;<br>
enum ENUM1* var2 = 0;<br>
<br>
<br>
enum ENUM2 {<br>
ENUM2_a = (enum ENUM2) 4,<br>
- ENUM2_b = 0x9FFFFFFF, // expected-warning {{enumerator value is not representable in the underlying type 'int'}}<br>
- ENUM2_c = 0x100000000 // expected-warning {{enumerator value is not representable in the underlying type 'int'}}<br>
+#ifdef WSIGNED_ENUMS<br>
+ // expected-warning@+3 {{enumerator value converted to underlying type 'int' with opposite sign}}<br>
+ // expected-warning@+3 {{enumerator value converted to underlying type 'int' with opposite sign}}<br>
+#endif<br>
+ ENUM2_b = ~0U,<br>
+ ENUM2_c = 0x9FFFFFFF,<br>
+ ENUM2_d = 0x100000000 // expected-warning {{enumerator value is not representable in the underlying type 'int'}}<br>
};<br>
<br>
__declspec(noreturn) void f6( void ) {<br>
</blockquote></div><br></div>