]> granicus.if.org Git - clang/commitdiff
Fix float->int conversion warnings when near barriers.
authorErich Keane <erich.keane@intel.com>
Tue, 8 May 2018 21:26:21 +0000 (21:26 +0000)
committerErich Keane <erich.keane@intel.com>
Tue, 8 May 2018 21:26:21 +0000 (21:26 +0000)
As Eli brought up here: https://reviews.llvm.org/D46535
I'd previously messed up this fix by missing conversions
that are just slightly outside the range.  This patch fixes
this by no longer ignoring the return value of
convertToInteger.  Additionally, one of the error messages
wasn't very sensical (mentioning out of range value, when it
really was not), so it was cleaned up as well.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@331812 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 9562aafd3a6f8c942f100f97240230c75de4e4a1..df77ee5fddec7278508fca4a78ab209e79a9878f 100644 (file)
@@ -3148,8 +3148,7 @@ def warn_impcast_float_integer : Warning<
   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">,
+  "implicit conversion 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">,
index 9652b6e23a76992c809521ed2ef6201f0755f9cb..8c5c789b29fb835eee688be71523711425240c23 100644 (file)
@@ -9419,26 +9419,25 @@ static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T,
 
   llvm::APSInt IntegerValue(S.Context.getIntWidth(T),
                             T->hasUnsignedIntegerRepresentation());
-  if (Value.convertToInteger(IntegerValue, llvm::APFloat::rmTowardZero,
-                             &isExact) == llvm::APFloat::opOK &&
-      isExact) {
+  llvm::APFloat::opStatus Result = Value.convertToInteger(
+      IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
+
+  if (Result == llvm::APFloat::opOK && isExact) {
     if (IsLiteral) return;
     return DiagnoseImpCast(S, E, T, CContext, diag::warn_impcast_float_integer,
                            PruneWarnings);
   }
 
+  // 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 && Result == llvm::APFloat::opInvalidOp)
+    return DiagnoseImpCast(
+        S, E, T, CContext,
+        IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
+                  : diag::warn_impcast_float_to_integer_out_of_range);
+
   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) {
@@ -9454,19 +9453,12 @@ static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T,
         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 cf1ead038f392f75af1e56f70e49321def4eede4..2e89acb3d681b44e00df94e361d8f6038b9bc54c 100644 (file)
@@ -63,6 +63,9 @@ void TestConstantFloat() {
 
   int b3 = five / 1.0;  //expected-warning{{conversion}}
   int b4 = five / 2.0;  //expected-warning{{conversion}}
+
+  int f = 2147483646.5 + 1; // expected-warning{{implicit conversion from 'double' to 'int' changes value from 2147483647.5 to 2147483647}}
+  unsigned g = -.5 + .01; // expected-warning{{implicit conversion from 'double' to 'unsigned int' changes non-zero value from -0.49 to 0}}
 }
 #endif  // FLOAT_CONVERSION
 
index 7efcf90fd963ef6c62fb1b92de07bce713feccff..b607bd8c76c4727bc3b85bc687007d1eedd0b261 100644 (file)
@@ -56,3 +56,7 @@ void test1() {
   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}}
 }
+
+int a() { return 2147483647.5; } // expected-warning{{implicit conversion from 'double' to 'int' changes value from 2147483647.5 to 2147483647}}
+unsigned b() { return -.5; } // expected-warning{{implicit conversion from 'double' to 'unsigned int' changes value from -0.5 to 0}}
+