folly/Conv.h: estimateSpaceNeeded: avoid undefined behavior
authorJim Meyering <meyering@fb.com>
Tue, 1 Dec 2015 05:17:20 +0000 (21:17 -0800)
committerfacebook-github-bot-0 <folly-bot@fb.com>
Tue, 1 Dec 2015 06:20:19 +0000 (22:20 -0800)
Summary: Do not negate signed numbers like INT_MIN or INTMAX_MIN, since
that would evoke undefined behavior.  Otherwise, the test (below)
would fail with this run-time error:

  [ RUN      ] Conv.Integral2String
  folly/Conv.h:521:47: runtime error: negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself

Reviewed By: markisaa

Differential Revision: D2704195

fb-gh-sync-id: 4036437fb972109672004163880078127e7df797

folly/Conv.h

index 8fdaef3bdfdd379d6cc8a5953edfce0bc934ee9d..ca6cbddf6aed413c24cd1fa980846b9c8b26d1c8 100644 (file)
@@ -513,7 +513,10 @@ typename std::enable_if<
   size_t>::type
 estimateSpaceNeeded(Src value) {
   if (value < 0) {
-    return 1 + digits10(static_cast<uint64_t>(-value));
+    // When "value" is the smallest negative, negating it would evoke
+    // undefined behavior, so, instead of writing "-value" below, we write
+    // "~static_cast<uint64_t>(value) + 1"
+    return 1 + digits10(~static_cast<uint64_t>(value) + 1);
   }
 
   return digits10(static_cast<uint64_t>(value));