Don't use a VLA for the double->string buffer.
authorChristopher Dykes <cdykes@fb.com>
Thu, 18 Feb 2016 23:24:48 +0000 (15:24 -0800)
committerfacebook-github-bot-4 <folly-bot@fb.com>
Fri, 19 Feb 2016 00:20:28 +0000 (16:20 -0800)
Summary: MSVC is actually smarter about this than GCC, as MSVC doesn't support VLAs, it tries to eval the length at compile time. GCC on the other hand doesn't try to eval it at compile time, resulting in compiles via CMake telling us that this is a VLA.

Reviewed By: yfeldblum

Differential Revision: D2911929

fb-gh-sync-id: ffaa133bcf4129a3e02f7e875966d3ae6a97be6a
shipit-source-id: ffaa133bcf4129a3e02f7e875966d3ae6a97be6a

folly/Format.cpp
folly/Makefile.am
folly/Portability.h
folly/Range.h
folly/json.cpp
folly/portability/Constexpr.h [new file with mode: 0755]

index d3a433ab06b51f2fcf6363d6b8fbdbe57638f957..0d1d61b126d19e7ad99be135922aef04575a4f68 100644 (file)
@@ -16,6 +16,8 @@
 
 #include <folly/Format.h>
 
+#include <folly/portability/Constexpr.h>
+
 #include <double-conversion/double-conversion.h>
 
 namespace folly {
@@ -48,11 +50,13 @@ void FormatValue<double>::formatHelper(
   }
 
   // 2+: for null terminator and optional sign shenanigans.
-  char buf[2 + std::max(
-      2 + DoubleToStringConverter::kMaxFixedDigitsBeforePoint +
-       DoubleToStringConverter::kMaxFixedDigitsAfterPoint,
-      std::max(8 + DoubleToStringConverter::kMaxExponentialDigits,
-      7 + DoubleToStringConverter::kMaxPrecisionDigits))];
+  constexpr size_t bufLen =
+      2 + constexpr_max(
+              2 + DoubleToStringConverter::kMaxFixedDigitsBeforePoint +
+                  DoubleToStringConverter::kMaxFixedDigitsAfterPoint,
+              constexpr_max(8 + DoubleToStringConverter::kMaxExponentialDigits,
+                            7 + DoubleToStringConverter::kMaxPrecisionDigits));
+  char buf[bufLen];
   StringBuilder builder(buf + 1, static_cast<int> (sizeof(buf) - 1));
 
   char plusSign;
index b4e5ecf702b13f8d7068705925c799eb8cb60db9..ddef486a9a476f3ff9d6af2a6995e4eda02d6c43 100644 (file)
@@ -263,6 +263,7 @@ nobase_follyinclude_HEADERS = \
        Padded.h \
        PicoSpinLock.h \
        Portability.h \
+       portability/Constexpr.h \
        portability/Syscall.h \
        portability/SysUio.h \
        Preprocessor.h \
index b35bdee89950cf8eb62de55a81f24e56998206be..a6241feaab0a641b0e1b067e68238d90e124f61d 100644 (file)
@@ -448,24 +448,6 @@ inline void asm_pause() {
 #endif
 }
 
-#ifdef _MSC_VER
-constexpr size_t constexpr_strlen_internal(const char* s, size_t len) {
-  return *s == '\0' ? len : constexpr_strlen_internal(s + 1, len + 1);
-}
-static_assert(constexpr_strlen_internal("123456789", 0) == 9,
-              "Someone appears to have broken constexpr_strlen...");
-#endif
-
-constexpr size_t constexpr_strlen(const char* s) {
-#if defined(__clang__)
-  return __builtin_strlen(s);
-#elif defined(_MSC_VER)
-  return s == nullptr ? 0 : constexpr_strlen_internal(s, 0);
-#else
-  return strlen(s);
-#endif
-}
-
 #if defined(__APPLE__) || defined(_MSC_VER)
 #define MAX_STATIC_CONSTRUCTOR_PRIORITY
 #else
index 3080626ac84a0f33c85bc479ca13e9167318e945..d42fe54872cee5b29454a6f80c82bebfc6c89c97 100644 (file)
@@ -23,6 +23,7 @@
 #include <folly/Portability.h>
 #include <folly/FBString.h>
 #include <folly/SpookyHashV2.h>
+#include <folly/portability/Constexpr.h>
 
 #include <algorithm>
 #include <boost/operators.hpp>
index 4d29a8979a3b2b1428bcf0b8e70540900d89b55d..4fb7d04acb131320c3100e21c20b796fb685ae49 100644 (file)
@@ -24,6 +24,7 @@
 #include <folly/Range.h>
 #include <folly/String.h>
 #include <folly/Unicode.h>
+#include <folly/portability/Constexpr.h>
 
 namespace folly {
 
diff --git a/folly/portability/Constexpr.h b/folly/portability/Constexpr.h
new file mode 100755 (executable)
index 0000000..810f987
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FOLLY_CONSTEXPR_H_
+#define FOLLY_CONSTEXPR_H_
+
+#include <cstdint>
+
+namespace folly {
+
+template <typename T>
+constexpr T constexpr_max(T a, T b) {
+  return a > b ? a : b;
+}
+
+template <typename T>
+constexpr T constexpr_min(T a, T b) {
+  return a < b ? a : b;
+}
+
+#ifdef _MSC_VER
+constexpr size_t constexpr_strlen_internal(const char* s, size_t len) {
+  return *s == '\0' ? len : constexpr_strlen_internal(s + 1, len + 1);
+}
+static_assert(constexpr_strlen_internal("123456789", 0) == 9,
+              "Someone appears to have broken constexpr_strlen...");
+#endif
+
+constexpr size_t constexpr_strlen(const char* s) {
+#if defined(__clang__)
+  return __builtin_strlen(s);
+#elif defined(_MSC_VER)
+  return s == nullptr ? 0 : constexpr_strlen_internal(s, 0);
+#else
+  return strlen(s);
+#endif
+}
+}
+
+#endif