erichkeane updated this revision to Diff 116244.
erichkeane marked 2 inline comments as done.
erichkeane added a comment.

Updated based on Eli's feedback.


https://reviews.llvm.org/D38145

Files:
  lib/Sema/SemaChecking.cpp
  test/SemaCXX/warn-sign-conversion-cpp11.cpp


Index: test/SemaCXX/warn-sign-conversion-cpp11.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/warn-sign-conversion-cpp11.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wsign-conversion -std=c++11 %s
+
+unsigned int test() {
+  short foo;
+  return foo; // expected-warning {{implicit conversion changes signedness}}
+
+}
+
+unsigned int test3() {
+  // For a non-defined enum, use the underlying type.
+  enum u8 : char;
+  u8 foo{static_cast<u8>(0)};
+  return foo; // expected-warning {{implicit conversion changes signedness}}
+
+}
+unsigned int test2() {
+  // For a non-defined enum, use the underlying type.
+  enum u8 : unsigned char;
+  u8 foo{static_cast<u8>(0)};
+  return foo;
+}
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -8171,8 +8171,12 @@
     // For enum types, use the known bit width of the enumerators.
     if (const EnumType *ET = dyn_cast<EnumType>(T)) {
       EnumDecl *Enum = ET->getDecl();
+      // Enums without definitions should use the signed-ness of the
+      // underlying type, so that when someone specifies the type as
+      // "unsigned" it doesn't cause sign-conversion type warnings.
       if (!Enum->isCompleteDefinition())
-        return IntRange(C.getIntWidth(QualType(T, 0)), false);
+        return IntRange(C.getIntWidth(QualType(T, 0)),
+                        !ET->isSignedIntegerOrEnumerationType());
 
       unsigned NumPositive = Enum->getNumPositiveBits();
       unsigned NumNegative = Enum->getNumNegativeBits();


Index: test/SemaCXX/warn-sign-conversion-cpp11.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/warn-sign-conversion-cpp11.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wsign-conversion -std=c++11 %s
+
+unsigned int test() {
+  short foo;
+  return foo; // expected-warning {{implicit conversion changes signedness}}
+
+}
+
+unsigned int test3() {
+  // For a non-defined enum, use the underlying type.
+  enum u8 : char;
+  u8 foo{static_cast<u8>(0)};
+  return foo; // expected-warning {{implicit conversion changes signedness}}
+
+}
+unsigned int test2() {
+  // For a non-defined enum, use the underlying type.
+  enum u8 : unsigned char;
+  u8 foo{static_cast<u8>(0)};
+  return foo;
+}
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -8171,8 +8171,12 @@
     // For enum types, use the known bit width of the enumerators.
     if (const EnumType *ET = dyn_cast<EnumType>(T)) {
       EnumDecl *Enum = ET->getDecl();
+      // Enums without definitions should use the signed-ness of the
+      // underlying type, so that when someone specifies the type as
+      // "unsigned" it doesn't cause sign-conversion type warnings.
       if (!Enum->isCompleteDefinition())
-        return IntRange(C.getIntWidth(QualType(T, 0)), false);
+        return IntRange(C.getIntWidth(QualType(T, 0)),
+                        !ET->isSignedIntegerOrEnumerationType());
 
       unsigned NumPositive = Enum->getNumPositiveBits();
       unsigned NumNegative = Enum->getNumNegativeBits();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to