summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErich Keane <erich.keane@intel.com>2018-05-08 21:26:21 +0000
committerErich Keane <erich.keane@intel.com>2018-05-08 21:26:21 +0000
commita4c48c68c5d4f8dfe2913520297c2d28a77ea239 (patch)
treefd745dd1616e6e94ddbb47c07792bbfdcddc4531
parent398612b4c2a9a7c2a45c18462d3c3e2d30fbad8b (diff)
downloadbcm5719-llvm-a4c48c68c5d4f8dfe2913520297c2d28a77ea239.tar.gz
bcm5719-llvm-a4c48c68c5d4f8dfe2913520297c2d28a77ea239.zip
Fix float->int conversion warnings when near barriers.
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. llvm-svn: 331812
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--clang/lib/Sema/SemaChecking.cpp32
-rw-r--r--clang/test/SemaCXX/warn-float-conversion.cpp3
-rw-r--r--clang/test/SemaCXX/warn-literal-conversion.cpp4
4 files changed, 20 insertions, 22 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9562aafd3a6..df77ee5fdde 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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">,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 9652b6e23a7..8c5c789b29f 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -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;
diff --git a/clang/test/SemaCXX/warn-float-conversion.cpp b/clang/test/SemaCXX/warn-float-conversion.cpp
index cf1ead038f3..2e89acb3d68 100644
--- a/clang/test/SemaCXX/warn-float-conversion.cpp
+++ b/clang/test/SemaCXX/warn-float-conversion.cpp
@@ -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
diff --git a/clang/test/SemaCXX/warn-literal-conversion.cpp b/clang/test/SemaCXX/warn-literal-conversion.cpp
index 7efcf90fd96..b607bd8c76c 100644
--- a/clang/test/SemaCXX/warn-literal-conversion.cpp
+++ b/clang/test/SemaCXX/warn-literal-conversion.cpp
@@ -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}}
+
OpenPOWER on IntegriCloud