Commit ad925ffa authored by Christopher Dykes's avatar Christopher Dykes Committed by facebook-github-bot-4

Don't use a VLA for the double->string buffer.

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
parent ca09289d
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include <folly/Format.h> #include <folly/Format.h>
#include <folly/portability/Constexpr.h>
#include <double-conversion/double-conversion.h> #include <double-conversion/double-conversion.h>
namespace folly { namespace folly {
...@@ -48,11 +50,13 @@ void FormatValue<double>::formatHelper( ...@@ -48,11 +50,13 @@ void FormatValue<double>::formatHelper(
} }
// 2+: for null terminator and optional sign shenanigans. // 2+: for null terminator and optional sign shenanigans.
char buf[2 + std::max( constexpr size_t bufLen =
2 + DoubleToStringConverter::kMaxFixedDigitsBeforePoint + 2 + constexpr_max(
DoubleToStringConverter::kMaxFixedDigitsAfterPoint, 2 + DoubleToStringConverter::kMaxFixedDigitsBeforePoint +
std::max(8 + DoubleToStringConverter::kMaxExponentialDigits, DoubleToStringConverter::kMaxFixedDigitsAfterPoint,
7 + DoubleToStringConverter::kMaxPrecisionDigits))]; constexpr_max(8 + DoubleToStringConverter::kMaxExponentialDigits,
7 + DoubleToStringConverter::kMaxPrecisionDigits));
char buf[bufLen];
StringBuilder builder(buf + 1, static_cast<int> (sizeof(buf) - 1)); StringBuilder builder(buf + 1, static_cast<int> (sizeof(buf) - 1));
char plusSign; char plusSign;
......
...@@ -263,6 +263,7 @@ nobase_follyinclude_HEADERS = \ ...@@ -263,6 +263,7 @@ nobase_follyinclude_HEADERS = \
Padded.h \ Padded.h \
PicoSpinLock.h \ PicoSpinLock.h \
Portability.h \ Portability.h \
portability/Constexpr.h \
portability/Syscall.h \ portability/Syscall.h \
portability/SysUio.h \ portability/SysUio.h \
Preprocessor.h \ Preprocessor.h \
......
...@@ -448,24 +448,6 @@ inline void asm_pause() { ...@@ -448,24 +448,6 @@ inline void asm_pause() {
#endif #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) #if defined(__APPLE__) || defined(_MSC_VER)
#define MAX_STATIC_CONSTRUCTOR_PRIORITY #define MAX_STATIC_CONSTRUCTOR_PRIORITY
#else #else
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <folly/Portability.h> #include <folly/Portability.h>
#include <folly/FBString.h> #include <folly/FBString.h>
#include <folly/SpookyHashV2.h> #include <folly/SpookyHashV2.h>
#include <folly/portability/Constexpr.h>
#include <algorithm> #include <algorithm>
#include <boost/operators.hpp> #include <boost/operators.hpp>
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <folly/Range.h> #include <folly/Range.h>
#include <folly/String.h> #include <folly/String.h>
#include <folly/Unicode.h> #include <folly/Unicode.h>
#include <folly/portability/Constexpr.h>
namespace folly { namespace folly {
......
/*
* 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment