Commit 1ac355bb by Abseil Team Committed by Copybara-Service

Add compile-checks to ensure the parameter to…

Add compile-checks to ensure the parameter to absl::numbers_internal::FastIntToBuffer isn't provably insufficient

This performance-sensitive API is internal, and should not be used directly. Nevertheless, some do use it, so it's worth trying to block incorrect uses where we can.

PiperOrigin-RevId: 594289730
Change-Id: Ib5df39b450ef2ceda795082cde10ec2ba2642172
parent f9228ec8
......@@ -138,4 +138,16 @@ ABSL_NAMESPACE_END
#define ABSL_INTERNAL_RETHROW do {} while (false)
#endif // ABSL_HAVE_EXCEPTIONS
// Requires the compiler to prove that the size of the given object is at least
// the expected amount.
#if ABSL_HAVE_ATTRIBUTE(diagnose_if) && ABSL_HAVE_BUILTIN(__builtin_object_size)
#define ABSL_INTERNAL_NEED_MIN_SIZE(Obj, N) \
__attribute__((diagnose_if(__builtin_object_size(Obj, 0) < N, \
"object size provably too small " \
"(this would corrupt memory)", \
"error")))
#else
#define ABSL_INTERNAL_NEED_MIN_SIZE(Obj, N)
#endif
#endif // ABSL_BASE_MACROS_H_
......@@ -166,18 +166,24 @@ static const int kSixDigitsToBufferSize = 16;
// Required buffer size is `kSixDigitsToBufferSize`.
size_t SixDigitsToBuffer(double d, absl::Nonnull<char*> buffer);
// These functions are intended for speed. All functions take an output buffer
// WARNING: These functions may write more characters than necessary, because
// they are intended for speed. All functions take an output buffer
// as an argument and return a pointer to the last byte they wrote, which is the
// terminating '\0'. At most `kFastToBufferSize` bytes are written.
absl::Nonnull<char*> FastIntToBuffer(int32_t, absl::Nonnull<char*>);
absl::Nonnull<char*> FastIntToBuffer(uint32_t, absl::Nonnull<char*>);
absl::Nonnull<char*> FastIntToBuffer(int64_t, absl::Nonnull<char*>);
absl::Nonnull<char*> FastIntToBuffer(uint64_t, absl::Nonnull<char*>);
absl::Nonnull<char*> FastIntToBuffer(int32_t i, absl::Nonnull<char*> buffer)
ABSL_INTERNAL_NEED_MIN_SIZE(buffer, kFastToBufferSize);
absl::Nonnull<char*> FastIntToBuffer(uint32_t i, absl::Nonnull<char*> buffer)
ABSL_INTERNAL_NEED_MIN_SIZE(buffer, kFastToBufferSize);
absl::Nonnull<char*> FastIntToBuffer(int64_t i, absl::Nonnull<char*> buffer)
ABSL_INTERNAL_NEED_MIN_SIZE(buffer, kFastToBufferSize);
absl::Nonnull<char*> FastIntToBuffer(uint64_t i, absl::Nonnull<char*> buffer)
ABSL_INTERNAL_NEED_MIN_SIZE(buffer, kFastToBufferSize);
// For enums and integer types that are not an exact match for the types above,
// use templates to call the appropriate one of the four overloads above.
template <typename int_type>
absl::Nonnull<char*> FastIntToBuffer(int_type i, absl::Nonnull<char*> buffer) {
absl::Nonnull<char*> FastIntToBuffer(int_type i, absl::Nonnull<char*> buffer)
ABSL_INTERNAL_NEED_MIN_SIZE(buffer, kFastToBufferSize) {
static_assert(sizeof(i) <= 64 / 8,
"FastIntToBuffer works only with 64-bit-or-less integers.");
// TODO(jorg): This signed-ness check is used because it works correctly
......
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