diff options
author | Richard Trieu <rtrieu@google.com> | 2018-05-14 23:21:48 +0000 |
---|---|---|
committer | Richard Trieu <rtrieu@google.com> | 2018-05-14 23:21:48 +0000 |
commit | a2b8fe660404a9594363e7b9721c1df4f27fd500 (patch) | |
tree | 6aebb6c8006161162f728dba0776fadd879bc9ca | |
parent | 9ae56b9a0e2f9769eddcbfb16feff28fce773edb (diff) | |
download | bcm5719-llvm-a2b8fe660404a9594363e7b9721c1df4f27fd500.tar.gz bcm5719-llvm-a2b8fe660404a9594363e7b9721c1df4f27fd500.zip |
Enable control flow pruning of float overflow warnings.
Like other conversion warnings, allow float overflow warnings to be disabled
in known dead paths of template instantiation. This often occurs when a
template template type is a numeric type and the template will check the
range of the numeric type before performing the conversion.
llvm-svn: 332310
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 3 | ||||
-rw-r--r-- | clang/test/SemaCXX/warn-float-conversion.cpp | 34 |
2 files changed, 36 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 74ecf5fef79..f8ab8a6b385 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -9673,7 +9673,8 @@ static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T, 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); + : diag::warn_impcast_float_to_integer_out_of_range, + PruneWarnings); unsigned DiagID = 0; if (IsLiteral) { diff --git a/clang/test/SemaCXX/warn-float-conversion.cpp b/clang/test/SemaCXX/warn-float-conversion.cpp index 2e89acb3d68..a3d178622c7 100644 --- a/clang/test/SemaCXX/warn-float-conversion.cpp +++ b/clang/test/SemaCXX/warn-float-conversion.cpp @@ -89,4 +89,38 @@ void TestOverflow() { char e = 1.0 / 0.0; // expected-warning{{implicit conversion of out of range value from 'double' to 'char' is undefined}} } + + +template <typename T> +class Check { + public: + static constexpr bool Safe(); +}; + +template<> +constexpr bool Check<char>::Safe() { return false; } + +template<> +constexpr bool Check<float>::Safe() { return true; } + +template <typename T> +T run1(T t) { + const float ret = 800; + return ret; // expected-warning {{implicit conversion of out of range value from 'const float' to 'char' is undefined}} +} + +template <typename T> +T run2(T t) { + const float ret = 800; + if (Check<T>::Safe()) + return ret; + else + return t; +} + +void test() { + float a = run1(a) + run2(a); + char b = run1(b) + run2(b); // expected-note {{in instantiation of function template specialization 'run1<char>' requested here}} +} + #endif // OVERFLOW |