erichkeane updated this revision to Diff 116245.
erichkeane marked an inline comment as done.

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 : signed 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,11 @@
     // For enum types, use the known bit width of the enumerators.
     if (const EnumType *ET = dyn_cast<EnumType>(T)) {
       EnumDecl *Enum = ET->getDecl();
+      // In C++11, enums without definitions can have an explicitly specified
+      // underlying type.  Use this type to compute the range.
       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 : signed 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,11 @@
     // For enum types, use the known bit width of the enumerators.
     if (const EnumType *ET = dyn_cast<EnumType>(T)) {
       EnumDecl *Enum = ET->getDecl();
+      // In C++11, enums without definitions can have an explicitly specified
+      // underlying type.  Use this type to compute the range.
       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