[libcxx] r289111 - [libcxx] [test] Fix MSVC warning C4244 "conversion from 'X' to 'Y', possible loss of data", part 7/7.

Stephan T. Lavavej via cfe-commits cfe-commits at lists.llvm.org
Thu Dec 8 13:38:57 PST 2016


Author: stl_msft
Date: Thu Dec  8 15:38:57 2016
New Revision: 289111

URL: http://llvm.org/viewvc/llvm-project?rev=289111&view=rev
Log:
[libcxx] [test] Fix MSVC warning C4244 "conversion from 'X' to 'Y', possible loss of data", part 7/7.

test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp
Add static_cast<char> because basic_istream::get() returns int_type (N4606 27.7.2.3 [istream.unformatted]/4).

test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minus1.pass.cpp
Add static_cast<char> because toupper() returns int (C11 7.4.2.2/1).

test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.ops/assign_t.pass.cpp
This test is intentionally writing doubles to ostream_iterator<int>.
It's silencing -Wliteral-conversion for Clang, so I'm adding C4244 silencing for MSVC.

test/std/language.support/support.limits/limits/numeric.limits.members/infinity.pass.cpp
Given `extern float zero;`, the expression `1./zero` has type double, which emits a truncation warning
when being passed to test<float>() taking float. The fix is to say `1.f/zero` which has type float.

test/std/numerics/complex.number/cmplx.over/arg.pass.cpp
test/std/numerics/complex.number/cmplx.over/norm.pass.cpp
These tests were constructing std::complex<double>(x, 0), emitting truncation warnings when x is long long.
Saying static_cast<double>(x) avoids this.

test/std/numerics/rand/rand.eng/rand.eng.lcong/seed_result_type.pass.cpp
This was using `int s` to construct and seed a linear_congruential_engine<T, stuff>, where T is
unsigned short/unsigned int/unsigned long/unsigned long long. That emits a truncation warning in the
unsigned short case. Because the range [0, 20) is tiny and we aren't doing anything else with the index,
we can just iterate with `T s`.

test/std/re/re.traits/value.pass.cpp
regex_traits<wchar_t>::value()'s first parameter is wchar_t (N4606 28.7 [re.traits]/13). This loop is
using int to iterate through ['g', 0xFFFF), emitting a truncation warning from int to wchar_t
(which is 16-bit for some of us). Because the bound is exclusive, we can just iterate with wchar_t.

test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp
This test is a little strange. It's trying to verify that basic_string's (InIt, InIt) range constructor
isn't confused by "N copies of C" when N and C have the same integral type. To do this, it was
testing (100, 65), but that eventually emits truncation warnings from int to char. There's a simple way
to avoid this - passing (static_cast<char>(100), static_cast<char>(65)) also exercises the disambiguation.
(And 100 is representable even when char has a signed range.)

test/std/strings/string.view/string.view.hash/string_view.pass.cpp
Add static_cast<char_type> because `'0' + i` has type int.

test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp
What's more horrible than nested bind()? pow() overloads! This operator()(T a, T b) was assuming that
std::pow(a, b) can be returned as T. (In this case, T is int.) However, N4606 26.9.1 [cmath.syn]/2
says that pow(int, int) returns double, so this was truncating double to int.
Adding static_cast<T> silences this.

test/std/utilities/function.objects/unord.hash/integral.pass.cpp
This was iterating `for (int i = 0; i <= 5; ++i)` and constructing `T t(i);` but that's truncating
when T is short. (And super truncating when T is bool.) Adding static_cast<T> silences this.

test/std/utilities/utility/exchange/exchange.pass.cpp
First, this was exchanging 67.2 into an int, but that's inherently truncating.
Changing this to static_cast<short>(67) avoids the truncation while preserving the
"what if T and U are different" test coverage.
Second, this was exchanging {} with the explicit type float into an int, and that's also
inherently truncating. Specifying short is just as good.

test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp
Add static_cast<short>. Note that this affects template argument deduction for make_pair(),
better fulfilling the test's intent. For example, this was saying
`typedef std::pair<int, short> P1; P1 p1 = std::make_pair(3, 4);` but that was asking
make_pair() to return pair<int, int>, which was then being converted to pair<int, short>.
(pair's converting constructors are tested elsewhere.)
Now, std::make_pair(3, static_cast<short>(4)) actually returns pair<int, short>.
(There's still a conversion from pair<nullptr_t, short> to pair<unique_ptr<int>, short>.)

Fixes D27544.

Modified:
    libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp
    libcxx/trunk/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minus1.pass.cpp
    libcxx/trunk/test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.ops/assign_t.pass.cpp
    libcxx/trunk/test/std/language.support/support.limits/limits/numeric.limits.members/infinity.pass.cpp
    libcxx/trunk/test/std/numerics/complex.number/cmplx.over/arg.pass.cpp
    libcxx/trunk/test/std/numerics/complex.number/cmplx.over/norm.pass.cpp
    libcxx/trunk/test/std/numerics/rand/rand.eng/rand.eng.lcong/seed_result_type.pass.cpp
    libcxx/trunk/test/std/re/re.traits/value.pass.cpp
    libcxx/trunk/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp
    libcxx/trunk/test/std/strings/string.view/string.view.hash/string_view.pass.cpp
    libcxx/trunk/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp
    libcxx/trunk/test/std/utilities/function.objects/unord.hash/integral.pass.cpp
    libcxx/trunk/test/std/utilities/utility/exchange/exchange.pass.cpp
    libcxx/trunk/test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp

Modified: libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp?rev=289111&r1=289110&r2=289111&view=diff
==============================================================================
--- libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp (original)
+++ libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp Thu Dec  8 15:38:57 2016
@@ -43,7 +43,7 @@ int main()
     {
         testbuf<char> sb("          ");
         std::istream is(&sb);
-        char c = is.get();
+        char c = static_cast<char>(is.get());
         assert(!is.eof());
         assert(!is.fail());
         assert(c == ' ');
@@ -52,22 +52,22 @@ int main()
     {
         testbuf<char> sb(" abc");
         std::istream is(&sb);
-        char c = is.get();
+        char c = static_cast<char>(is.get());
         assert(!is.eof());
         assert(!is.fail());
         assert(c == ' ');
         assert(is.gcount() == 1);
-        c = is.get();
+        c = static_cast<char>(is.get());
         assert(!is.eof());
         assert(!is.fail());
         assert(c == 'a');
         assert(is.gcount() == 1);
-        c = is.get();
+        c = static_cast<char>(is.get());
         assert(!is.eof());
         assert(!is.fail());
         assert(c == 'b');
         assert(is.gcount() == 1);
-        c = is.get();
+        c = static_cast<char>(is.get());
         assert(!is.eof());
         assert(!is.fail());
         assert(c == 'c');

Modified: libcxx/trunk/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minus1.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minus1.pass.cpp?rev=289111&r1=289110&r2=289111&view=diff
==============================================================================
--- libcxx/trunk/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minus1.pass.cpp (original)
+++ libcxx/trunk/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/minus1.pass.cpp Thu Dec  8 15:38:57 2016
@@ -51,7 +51,7 @@ void test_hex(const char *expected)
 
     std::string str = ss.str();
     for (size_t i = 0; i < str.size(); ++i )
-        str[i] = std::toupper(str[i]);
+        str[i] = static_cast<char>(std::toupper(str[i]));
 
     assert(str == expected);
 }

Modified: libcxx/trunk/test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.ops/assign_t.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.ops/assign_t.pass.cpp?rev=289111&r1=289110&r2=289111&view=diff
==============================================================================
--- libcxx/trunk/test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.ops/assign_t.pass.cpp (original)
+++ libcxx/trunk/test/std/iterators/stream.iterators/ostream.iterator/ostream.iterator.ops/assign_t.pass.cpp Thu Dec  8 15:38:57 2016
@@ -21,6 +21,10 @@
 #pragma clang diagnostic ignored "-Wliteral-conversion"
 #endif
 
+#ifdef _MSC_VER
+#pragma warning(disable: 4244) // conversion from 'X' to 'Y', possible loss of data
+#endif
+
 int main()
 {
     {

Modified: libcxx/trunk/test/std/language.support/support.limits/limits/numeric.limits.members/infinity.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.limits/limits/numeric.limits.members/infinity.pass.cpp?rev=289111&r1=289110&r2=289111&view=diff
==============================================================================
--- libcxx/trunk/test/std/language.support/support.limits/limits/numeric.limits.members/infinity.pass.cpp (original)
+++ libcxx/trunk/test/std/language.support/support.limits/limits/numeric.limits.members/infinity.pass.cpp Thu Dec  8 15:38:57 2016
@@ -50,7 +50,7 @@ int main()
     test<__int128_t>(0);
     test<__uint128_t>(0);
 #endif
-    test<float>(1./zero);
+    test<float>(1.f/zero);
     test<double>(1./zero);
     test<long double>(1./zero);
 }

Modified: libcxx/trunk/test/std/numerics/complex.number/cmplx.over/arg.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/numerics/complex.number/cmplx.over/arg.pass.cpp?rev=289111&r1=289110&r2=289111&view=diff
==============================================================================
--- libcxx/trunk/test/std/numerics/complex.number/cmplx.over/arg.pass.cpp (original)
+++ libcxx/trunk/test/std/numerics/complex.number/cmplx.over/arg.pass.cpp Thu Dec  8 15:38:57 2016
@@ -24,7 +24,7 @@ void
 test(T x, typename std::enable_if<std::is_integral<T>::value>::type* = 0)
 {
     static_assert((std::is_same<decltype(std::arg(x)), double>::value), "");
-    assert(std::arg(x) == arg(std::complex<double>(x, 0)));
+    assert(std::arg(x) == arg(std::complex<double>(static_cast<double>(x), 0)));
 }
 
 template <class T>

Modified: libcxx/trunk/test/std/numerics/complex.number/cmplx.over/norm.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/numerics/complex.number/cmplx.over/norm.pass.cpp?rev=289111&r1=289110&r2=289111&view=diff
==============================================================================
--- libcxx/trunk/test/std/numerics/complex.number/cmplx.over/norm.pass.cpp (original)
+++ libcxx/trunk/test/std/numerics/complex.number/cmplx.over/norm.pass.cpp Thu Dec  8 15:38:57 2016
@@ -24,7 +24,7 @@ void
 test(T x, typename std::enable_if<std::is_integral<T>::value>::type* = 0)
 {
     static_assert((std::is_same<decltype(std::norm(x)), double>::value), "");
-    assert(std::norm(x) == norm(std::complex<double>(x, 0)));
+    assert(std::norm(x) == norm(std::complex<double>(static_cast<double>(x), 0)));
 }
 
 template <class T>

Modified: libcxx/trunk/test/std/numerics/rand/rand.eng/rand.eng.lcong/seed_result_type.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/numerics/rand/rand.eng/rand.eng.lcong/seed_result_type.pass.cpp?rev=289111&r1=289110&r2=289111&view=diff
==============================================================================
--- libcxx/trunk/test/std/numerics/rand/rand.eng/rand.eng.lcong/seed_result_type.pass.cpp (original)
+++ libcxx/trunk/test/std/numerics/rand/rand.eng/rand.eng.lcong/seed_result_type.pass.cpp Thu Dec  8 15:38:57 2016
@@ -21,7 +21,7 @@ template <class T>
 void
 test1()
 {
-    for (int s = 0; s < 20; ++s)
+    for (T s = 0; s < 20; ++s)
     {
         typedef std::linear_congruential_engine<T, 2, 3, 7> E;
         E e1(s);

Modified: libcxx/trunk/test/std/re/re.traits/value.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/re/re.traits/value.pass.cpp?rev=289111&r1=289110&r2=289111&view=diff
==============================================================================
--- libcxx/trunk/test/std/re/re.traits/value.pass.cpp (original)
+++ libcxx/trunk/test/std/re/re.traits/value.pass.cpp Thu Dec  8 15:38:57 2016
@@ -116,7 +116,7 @@ int main()
             assert(t.value(c, 10) == -1);
             assert(t.value(c, 16) == c - 'a' +10);
         }
-        for (int c = 'g'; c < 0xFFFF; ++c)
+        for (wchar_t c = 'g'; c < 0xFFFF; ++c)
         {
             assert(t.value(c, 8) == -1);
             assert(t.value(c, 10) == -1);

Modified: libcxx/trunk/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp?rev=289111&r1=289110&r2=289111&view=diff
==============================================================================
--- libcxx/trunk/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp (original)
+++ libcxx/trunk/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp Thu Dec  8 15:38:57 2016
@@ -103,8 +103,8 @@ int main()
     test(100, 'a');
     test(100, 'a', A(2));
 
-    test(100, 65);
-    test(100, 65, A(3));
+    test(static_cast<char>(100), static_cast<char>(65));
+    test(static_cast<char>(100), static_cast<char>(65), A(3));
     }
 #if TEST_STD_VER >= 11
     {
@@ -123,8 +123,8 @@ int main()
     test(100, 'a');
     test(100, 'a', A());
 
-    test(100, 65);
-    test(100, 65, A());
+    test(static_cast<char>(100), static_cast<char>(65));
+    test(static_cast<char>(100), static_cast<char>(65), A());
     }
 #endif
 }

Modified: libcxx/trunk/test/std/strings/string.view/string.view.hash/string_view.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/strings/string.view/string.view.hash/string_view.pass.cpp?rev=289111&r1=289110&r2=289111&view=diff
==============================================================================
--- libcxx/trunk/test/std/strings/string.view/string.view.hash/string_view.pass.cpp (original)
+++ libcxx/trunk/test/std/strings/string.view/string.view.hash/string_view.pass.cpp Thu Dec  8 15:38:57 2016
@@ -38,7 +38,7 @@ test()
     char_type g1 [ 10 ];
     char_type g2 [ 10 ];
     for ( int i = 0; i < 10; ++i )
-        g1[i] = g2[9-i] = '0' + i;
+        g1[i] = g2[9-i] = static_cast<char_type>('0' + i);
     T s1(g1, 10);
     T s2(g2, 10);
     assert(h(s1) != h(s2));

Modified: libcxx/trunk/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp?rev=289111&r1=289110&r2=289111&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp Thu Dec  8 15:38:57 2016
@@ -28,7 +28,7 @@ struct power
   T
   operator()(T a, T b)
   {
-    return std::pow(a, b);
+    return static_cast<T>(std::pow(a, b));
   }
 };
 

Modified: libcxx/trunk/test/std/utilities/function.objects/unord.hash/integral.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/function.objects/unord.hash/integral.pass.cpp?rev=289111&r1=289110&r2=289111&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/function.objects/unord.hash/integral.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/function.objects/unord.hash/integral.pass.cpp Thu Dec  8 15:38:57 2016
@@ -35,7 +35,7 @@ test()
 
     for (int i = 0; i <= 5; ++i)
     {
-        T t(i);
+        T t(static_cast<T>(i));
         if (sizeof(T) <= sizeof(std::size_t))
         {
             const std::size_t result = h(t);

Modified: libcxx/trunk/test/std/utilities/utility/exchange/exchange.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/utility/exchange/exchange.pass.cpp?rev=289111&r1=289110&r2=289111&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/utility/exchange/exchange.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/utility/exchange/exchange.pass.cpp Thu Dec  8 15:38:57 2016
@@ -22,10 +22,10 @@ int main()
     int v = 12;
     assert ( std::exchange ( v, 23 ) == 12 );
     assert ( v == 23 );
-    assert ( std::exchange ( v, 67.2 ) == 23 );
+    assert ( std::exchange ( v, static_cast<short>(67) ) == 23 );
     assert ( v == 67 );
 
-    assert ((std::exchange<int, float> ( v, {} )) == 67 );
+    assert ((std::exchange<int, short> ( v, {} )) == 67 );
     assert ( v == 0 );
 
     }

Modified: libcxx/trunk/test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp?rev=289111&r1=289110&r2=289111&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp Thu Dec  8 15:38:57 2016
@@ -21,7 +21,7 @@ int main()
 {
     {
         typedef std::pair<int, short> P1;
-        P1 p1 = std::make_pair(3, 4);
+        P1 p1 = std::make_pair(3, static_cast<short>(4));
         assert(p1.first == 3);
         assert(p1.second == 4);
     }
@@ -29,13 +29,13 @@ int main()
 #if TEST_STD_VER >= 11
     {
         typedef std::pair<std::unique_ptr<int>, short> P1;
-        P1 p1 = std::make_pair(std::unique_ptr<int>(new int(3)), 4);
+        P1 p1 = std::make_pair(std::unique_ptr<int>(new int(3)), static_cast<short>(4));
         assert(*p1.first == 3);
         assert(p1.second == 4);
     }
     {
         typedef std::pair<std::unique_ptr<int>, short> P1;
-        P1 p1 = std::make_pair(nullptr, 4);
+        P1 p1 = std::make_pair(nullptr, static_cast<short>(4));
         assert(p1.first == nullptr);
         assert(p1.second == 4);
     }
@@ -43,7 +43,7 @@ int main()
 #if TEST_STD_VER >= 14
     {
         typedef std::pair<int, short> P1;
-        constexpr P1 p1 = std::make_pair(3, 4);
+        constexpr P1 p1 = std::make_pair(3, static_cast<short>(4));
         static_assert(p1.first == 3, "");
         static_assert(p1.second == 4, "");
     }




More information about the cfe-commits mailing list