summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td6
-rw-r--r--clang/lib/Sema/SemaChecking.cpp17
-rw-r--r--clang/test/SemaCXX/coroutines.cpp2
-rw-r--r--clang/test/SemaCXX/warn-float-conversion.cpp6
-rw-r--r--clang/test/SemaCXX/warn-literal-conversion.cpp7
5 files changed, 34 insertions, 4 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 03988a17e01..a015f45feb4 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3140,6 +3140,9 @@ def warn_impcast_bitfield_precision_constant : Warning<
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;
@@ -3148,6 +3151,9 @@ 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;
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 8cc8330ea3a..9652b6e23a7 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;
diff --git a/clang/test/SemaCXX/coroutines.cpp b/clang/test/SemaCXX/coroutines.cpp
index 2c979f5b30d..0d0588dbbf0 100644
--- a/clang/test/SemaCXX/coroutines.cpp
+++ b/clang/test/SemaCXX/coroutines.cpp
@@ -157,7 +157,7 @@ struct coroutine_handle<void> {
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}}
diff --git a/clang/test/SemaCXX/warn-float-conversion.cpp b/clang/test/SemaCXX/warn-float-conversion.cpp
index fc221893aee..cf1ead038f3 100644
--- a/clang/test/SemaCXX/warn-float-conversion.cpp
+++ b/clang/test/SemaCXX/warn-float-conversion.cpp
@@ -81,9 +81,9 @@ void TestOverflow() {
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
diff --git a/clang/test/SemaCXX/warn-literal-conversion.cpp b/clang/test/SemaCXX/warn-literal-conversion.cpp
index 875aa1dec5e..7efcf90fd96 100644
--- a/clang/test/SemaCXX/warn-literal-conversion.cpp
+++ b/clang/test/SemaCXX/warn-literal-conversion.cpp
@@ -48,4 +48,11 @@ void test1() {
// 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}}
}
OpenPOWER on IntegriCloud