diff options
author | Erich Keane <erich.keane@intel.com> | 2018-05-07 20:52:56 +0000 |
---|---|---|
committer | Erich Keane <erich.keane@intel.com> | 2018-05-07 20:52:56 +0000 |
commit | 8052cdc6396773b874b2b1d54c6c4f52445d2b72 (patch) | |
tree | b59df3193bc10ef0a40327d8f971cd08713a10ac /lib/Sema/SemaChecking.cpp | |
parent | ffe5542eab6ccd9b09e1a4a951993e230d4f88a4 (diff) | |
download | clang-8052cdc6396773b874b2b1d54c6c4f52445d2b72.tar.gz |
Correct warning on Float->Integer conversions.
As identified and briefly discussed here:
https://bugs.llvm.org/show_bug.cgi?id=37305
Converting a floating point number to an integer type when
the integral part is out of the range of the integer type is
undefined behavior in C. Additionally, CodeGen emits an undef
in this situation.
HOWEVER, we've been giving a warning that says that the value is
changed. This patch corrects the warning to list that it is actually
undefined behavior.
Differential Revision: https://reviews.llvm.org/D46535
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@331673 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 8cc8330ea3..9652b6e23a 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -9429,6 +9429,16 @@ static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T, 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 @@ 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; |