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 | 7130a93934707ed10c1a1bab8b423e7c3123a30d (patch) | |
tree | cd3f3e555ef9e4206d1142fdf7ebdfb3e22f6db2 /clang/lib/Sema/SemaChecking.cpp | |
parent | 1233e1234ab8466b7997cc0a50683f85061b5e64 (diff) | |
download | llvm-7130a93934707ed10c1a1bab8b423e7c3123a30d.zip llvm-7130a93934707ed10c1a1bab8b423e7c3123a30d.tar.gz llvm-7130a93934707ed10c1a1bab8b423e7c3123a30d.tar.bz2 |
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
llvm-svn: 331673
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 8cc8330..9652b6e 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/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; |