This revision was automatically updated to reflect the committed changes.
Closed by commit rC331673: Correct warning on Float->Integer conversions. 
(authored by erichkeane, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D46535?vs=145536&id=145542#toc

Repository:
  rC Clang

https://reviews.llvm.org/D46535

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaChecking.cpp
  test/SemaCXX/coroutines.cpp
  test/SemaCXX/warn-float-conversion.cpp
  test/SemaCXX/warn-literal-conversion.cpp

Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -9429,6 +9429,16 @@
 
   unsigned DiagID = 0;
   if (IsLiteral) {
+    // Conversion of a floating-point value to a non-bool integer where the
+    // integral part cannot be represented by the integer type is undefined.
+    if (!IsBool &&
+        ((IntegerValue.isSigned() && (IntegerValue.isMaxSignedValue() ||
+                                      IntegerValue.isMinSignedValue())) ||
+         (IntegerValue.isUnsigned() &&
+          (IntegerValue.isMaxValue() || IntegerValue.isMinValue()))))
+      return DiagnoseImpCast(
+          S, E, T, CContext,
+          diag::warn_impcast_literal_float_to_integer_out_of_range);
     // Warn on floating point literal to integer.
     DiagID = diag::warn_impcast_literal_float_to_integer;
   } else if (IntegerValue == 0) {
@@ -9444,12 +9454,19 @@
         return DiagnoseImpCast(S, E, T, CContext,
                                diag::warn_impcast_float_integer, PruneWarnings);
       }
+      if (!IsBool && (IntegerValue.isMaxValue() || IntegerValue.isMinValue()))
+        return DiagnoseImpCast(S, E, T, CContext,
+                               diag::warn_impcast_float_to_integer_out_of_range,
+                               PruneWarnings);
     } else {  // IntegerValue.isSigned()
       if (!IntegerValue.isMaxSignedValue() &&
           !IntegerValue.isMinSignedValue()) {
         return DiagnoseImpCast(S, E, T, CContext,
                                diag::warn_impcast_float_integer, PruneWarnings);
       }
+      return DiagnoseImpCast(S, E, T, CContext,
+                             diag::warn_impcast_float_to_integer_out_of_range,
+                             PruneWarnings);
     }
     // Warn on evaluatable floating point expression to integer conversion.
     DiagID = diag::warn_impcast_float_to_integer;
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -3140,14 +3140,20 @@
 def warn_impcast_literal_float_to_integer : Warning<
   "implicit conversion from %0 to %1 changes value from %2 to %3">,
   InGroup<LiteralConversion>;
+def warn_impcast_literal_float_to_integer_out_of_range : Warning<
+  "implicit conversion of out of range value from %0 to %1 is undefined">,
+  InGroup<LiteralConversion>;
 def warn_impcast_float_integer : Warning<
   "implicit conversion turns floating-point number into integer: %0 to %1">,
   InGroup<FloatConversion>, DefaultIgnore;
 
 def warn_impcast_float_to_integer : Warning<
   "implicit conversion of out of range value from %0 to %1 changes value "
   "from %2 to %3">,
   InGroup<FloatOverflowConversion>, DefaultIgnore;
+def warn_impcast_float_to_integer_out_of_range : Warning<
+  "implicit conversion of out of range value from %0 to %1 is undefined">,
+  InGroup<FloatOverflowConversion>, DefaultIgnore;
 def warn_impcast_float_to_integer_zero : Warning<
   "implicit conversion from %0 to %1 changes non-zero value from %2 to %3">,
   InGroup<FloatZeroConversion>, DefaultIgnore;
Index: test/SemaCXX/coroutines.cpp
===================================================================
--- test/SemaCXX/coroutines.cpp
+++ test/SemaCXX/coroutines.cpp
@@ -157,7 +157,7 @@
 void yield() {
   co_yield 0;
   co_yield {"foo", 1, 2};
-  co_yield {1e100}; // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{changes value}} expected-warning {{braces around scalar}}
+  co_yield {1e100}; // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{implicit conversion}} expected-warning {{braces around scalar}}
   co_yield {"foo", __LONG_LONG_MAX__}; // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{changes value}}
   co_yield {"foo"};
   co_yield "foo"; // expected-error {{no matching}}
Index: test/SemaCXX/warn-float-conversion.cpp
===================================================================
--- test/SemaCXX/warn-float-conversion.cpp
+++ test/SemaCXX/warn-float-conversion.cpp
@@ -81,9 +81,9 @@
   char b = -500.0;  // caught by -Wliteral-conversion
 
   const float LargeNumber = 1024;
-  char c = LargeNumber;  // expected-warning{{implicit conversion of out of range value from 'const float' to 'char' changes value from 1024 to 127}}
-  char d = 400.0 + 400.0;  // expected-warning{{implicit conversion of out of range value from 'double' to 'char' changes value from 800 to 127}}
+  char c = LargeNumber;  // expected-warning{{implicit conversion of out of range value from 'const float' to 'char' is undefined}}
+  char d = 400.0 + 400.0;  // expected-warning{{implicit conversion of out of range value from 'double' to 'char' is undefined}}
 
-  char e = 1.0 / 0.0;  // expected-warning{{implicit conversion of out of range value from 'double' to 'char' changes value from +Inf to 127}}
+  char e = 1.0 / 0.0;  // expected-warning{{implicit conversion of out of range value from 'double' to 'char' is undefined}}
 }
 #endif  // OVERFLOW
Index: test/SemaCXX/warn-literal-conversion.cpp
===================================================================
--- test/SemaCXX/warn-literal-conversion.cpp
+++ test/SemaCXX/warn-literal-conversion.cpp
@@ -48,4 +48,11 @@
   // values.
   bool b3 = 0.0f;
   bool b4 = 0.0;
+
+  // These all warn because they overflow the target type.
+  short s = 32768.0; // expected-warning{{implicit conversion of out of range value from 'double' to 'short' is undefined}}
+  unsigned short us = 65536.0; // expected-warning{{implicit conversion of out of range value from 'double' to 'unsigned short' is undefined}}
+
+  short s2 = -32769.0; // expected-warning{{implicit conversion of out of range value from 'double' to 'short' is undefined}}
+  unsigned short us2 = -65537.0; // expected-warning{{implicit conversion of out of range value from 'double' to 'unsigned short' is undefined}}
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to