folly/Conv.h: suppress -Wfloat-conversion warnings
authorJim Meyering <meyering@fb.com>
Tue, 1 Dec 2015 15:27:54 +0000 (07:27 -0800)
committerfacebook-github-bot-0 <folly-bot@fb.com>
Tue, 1 Dec 2015 16:20:19 +0000 (08:20 -0800)
Summary: Using -Werror and -Wfloat-conversion was causing failure in code that is deliberately
performing that conversion.  Add explicit casts to avoid the warnings/errors.
Here are two of the diagnostics:

  ./folly/Conv.h: In instantiation of "typename std::enable_if<std::is_floating_point<_Tp>::value, Tgt>::type folly::to(folly::StringPiece) [with Tgt = float; typename std::enable_if<std::is_floating_point<_Tp>::value, Tgt>::type = float; folly::StringPiece = folly::Range<const char*>]":
  ./thrift/lib/cpp2/protocol/SimpleJSONProtocol.tcc:687:28:   required from "T apache::thrift::SimpleJSONProtocolReader::castIntegral(const string&) [with T = float; std::string = std::basic_fbstring<char>]"
  ./thrift/lib/cpp2/protocol/SimpleJSONProtocol.tcc:680:26:   required from "uint32_t apache::thrift::SimpleJSONProtocolReader::readJSONKey(T&) [with T = float; uint32_t = unsigned int]"
  ./thrift/lib/cpp2/protocol/SimpleJSONProtocol.tcc:654:16:   required from "uint32_t apache::thrift::SimpleJSONProtocolReader::readInContext(T&) [with T = float; uint32_t = unsigned int]"
  ./thrift/lib/cpp2/protocol/SimpleJSONProtocol.tcc:1035:34:   required from here
  ./folly/Conv.h:1222:31: error: conversion to "float" from "std::enable_if<true, double>::type {aka double}" may alter its value [-Werror=float-conversion]

  ./folly/Conv.h: In instantiation of "typename std::enable_if<((std::is_integral<_Tp2>::value && std::is_floating_point<_Tp>::value) || (std::is_floating_point<_DInputType>::value && std::is_integral<_Tp>::value)), Tgt>::type folly::to(const Src&) [with Tgt = long int; Src = double; typename std::enable_if<((std::is_integral<_Tp2>::value && std::is_floating_point<_Tp>::value) || (std::is_floating_point<_DInputType>::value && std::is_integral<_Tp>::value)), Tgt>::type = long int]":
  ./folly/dynamic-inl.h:636:51:   required from "T folly::dynamic::asImpl() const [with T = long int]"
  ./folly/dynamic-inl.h:384:64:   required from here
  ./folly/Conv.h:1245:16: error: conversion to "long int" from "double" may alter its value [-Werror=float-conversion]

This change deserves a little more explanation:

  -  return ceil((double(sizeof(IntegerType) * CHAR_BIT) * M_LN2) / M_LN10);
  +  return (unsigned int)(ceil(sizeof(IntegerType) * CHAR_BIT * M_LN2 / M_LN10));

In addition to adding the cast to destination type, I have also removed the unnecessary cast to double of the first product (there is not risk that it will overflow, and no need to promote to double, there), and I have also removed the grouping parentheses, since the standard left-to-right evaluation works just fine here.

Reviewed By: Gownta, yfeldblum

Differential Revision: D2703928

fb-gh-sync-id: 23b49281d9120d106f1fdbd30921e8f39c01367d

folly/Conv.h

index ca6cbddf6aed413c24cd1fa980846b9c8b26d1c8..b91c4e60d6b39a70eacd5951ddd1089e2fc13f0d 100644 (file)
@@ -202,7 +202,7 @@ namespace detail {
 template <typename IntegerType>
 constexpr unsigned int
 digitsEnough() {
-  return ceil((double(sizeof(IntegerType) * CHAR_BIT) * M_LN2) / M_LN10);
+  return (unsigned int)(ceil(sizeof(IntegerType) * CHAR_BIT * M_LN2 / M_LN10));
 }
 
 inline size_t
@@ -1222,7 +1222,7 @@ typename std::enable_if<
   std::is_floating_point<Tgt>::value,
   Tgt>::type
 to(StringPiece src) {
-  Tgt result = to<double>(&src);
+  Tgt result = Tgt(to<double>(&src));
   detail::enforceWhitespace(src.data(), src.data() + src.size());
   return result;
 }
@@ -1245,7 +1245,7 @@ typename std::enable_if<
   (std::is_floating_point<Src>::value && std::is_integral<Tgt>::value),
   Tgt>::type
 to(const Src & value) {
-  Tgt result = value;
+  Tgt result = Tgt(value);
   auto witness = static_cast<Src>(result);
   if (value != witness) {
     throw std::range_error(