mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 04:41:11 +00:00
Bug 1717448 - Print the diagnostic message in AssertedCast with {fmt}. r=nbp
Differential Revision: https://phabricator.services.mozilla.com/D216967
This commit is contained in:
parent
7f874ba600
commit
6a1d862d72
@ -12,6 +12,8 @@
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include <cinttypes>
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
@ -82,44 +84,54 @@ constexpr uint64_t safe_integer_unsigned() {
|
||||
|
||||
template <typename T>
|
||||
const char* TypeToString();
|
||||
template <typename T>
|
||||
const char* TypeToFormatString();
|
||||
|
||||
#define T2S(type, formatstring) \
|
||||
template <> \
|
||||
inline constexpr const char* TypeToString<type>() { \
|
||||
return #type; \
|
||||
} \
|
||||
template <> \
|
||||
inline constexpr const char* TypeToFormatString<type>() { \
|
||||
return "%" formatstring; \
|
||||
#define T2S(type) \
|
||||
template <> \
|
||||
inline constexpr const char* TypeToString<type>() { \
|
||||
return #type; \
|
||||
}
|
||||
|
||||
T2S(uint8_t, PRIu8);
|
||||
T2S(uint16_t, PRIu16);
|
||||
T2S(uint32_t, PRIu32);
|
||||
T2S(uint64_t, PRIu64);
|
||||
T2S(int8_t, PRId8);
|
||||
T2S(int16_t, PRId16);
|
||||
T2S(int32_t, PRId32);
|
||||
T2S(int64_t, PRId64);
|
||||
T2S(char16_t, PRIu16); // print as a number
|
||||
T2S(char32_t, PRIu32); // print as a number
|
||||
T2S(uint8_t);
|
||||
T2S(uint16_t);
|
||||
T2S(uint32_t);
|
||||
T2S(uint64_t);
|
||||
T2S(int8_t);
|
||||
T2S(int16_t);
|
||||
T2S(int32_t);
|
||||
T2S(int64_t);
|
||||
T2S(char16_t);
|
||||
T2S(char32_t);
|
||||
#if defined(XP_DARWIN) || defined(XP_WIN) || defined(__wasm__)
|
||||
T2S(long, "ld");
|
||||
T2S(unsigned long, "lu");
|
||||
T2S(long);
|
||||
T2S(unsigned long);
|
||||
#endif
|
||||
T2S(float, "f");
|
||||
T2S(double, "lf");
|
||||
T2S(float);
|
||||
T2S(double);
|
||||
|
||||
#undef T2S
|
||||
|
||||
template <typename In, typename Out>
|
||||
inline void DiagnosticMessage(In aIn, char aDiagnostic[1024]) {
|
||||
char number[128];
|
||||
SprintfBuf(number, 128, TypeToFormatString<In>(), aIn);
|
||||
SprintfBuf(aDiagnostic, 1024, "Cannot cast %s from %s to %s: out of range",
|
||||
number, TypeToString<In>(), TypeToString<Out>());
|
||||
if constexpr (std::is_same_v<In, char> || std::is_same_v<In, wchar_t> ||
|
||||
std::is_same_v<In, char16_t> || std::is_same_v<In, char32_t>) {
|
||||
static_assert(sizeof(wchar_t) <= sizeof(int32_t));
|
||||
// Characters types are printed in hexadecimal for two reasons:
|
||||
// - to easily debug problems with non-printable characters.
|
||||
// - {fmt} refuses to format a string with mixed character type.
|
||||
// It's always possible to cast them to int64_t for lossless printing of the
|
||||
// value.
|
||||
auto [out, size] = fmt::format_to_n(
|
||||
aDiagnostic, 1023,
|
||||
FMT_STRING("Cannot cast {:x} from {} to {}: out of range"),
|
||||
static_cast<int64_t>(aIn), TypeToString<In>(), TypeToString<Out>());
|
||||
*out = 0;
|
||||
} else {
|
||||
auto [out, size] = fmt::format_to_n(
|
||||
aDiagnostic, 1023,
|
||||
FMT_STRING("Cannot cast {} from {} to {}: out of range"), aIn,
|
||||
TypeToString<In>(), TypeToString<Out>());
|
||||
*out = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// This is working around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81676,
|
||||
|
Loading…
Reference in New Issue
Block a user