Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into fuzz
Browse files Browse the repository at this point in the history
# Conflicts:
#	include/fmt/chrono.h
  • Loading branch information
pauldreik committed Jun 14, 2019
2 parents 7842582 + 12f4683 commit 9a3f4cf
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 62 deletions.
34 changes: 26 additions & 8 deletions include/fmt/chrono.h
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
inline bool isnan(T value) {
return std::isnan(value);
}

template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
inline bool isfinite(T) {
return true;
Expand All @@ -396,6 +397,8 @@ template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
inline bool isfinite(T value) {
return std::isfinite(value);
}

//paul - is this fcn unused?
template <typename T> inline int to_int(T value) {
FMT_ASSERT(!isnan(value), "nan to int conversion is UB");
if (std::numeric_limits<T>::is_signed) {
Expand All @@ -409,6 +412,20 @@ template <typename T> inline int to_int(T value) {
return static_cast<int>(value);
}

// Convers value to int and checks that it's in the range [0, upper).
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
inline int to_nonnegative_int(T value, int upper) {
FMT_ASSERT(value >= 0 && value <= upper, "invalid value");
return static_cast<int>(value);
}
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
inline int to_nonnegative_int(T value, int upper) {
FMT_ASSERT(
std::isnan(value) || (value >= 0 && value <= static_cast<T>(upper)),
"invalid value");
return static_cast<int>(value);
}

template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
inline T mod(T x, int y) {
return x % y;
Expand Down Expand Up @@ -560,9 +577,9 @@ struct chrono_formatter {

std::tm time() const {
auto time = std::tm();
time.tm_hour = to_int(hour());
time.tm_min = to_int(minute());
time.tm_sec = to_int(second());
time.tm_hour = to_nonnegative_int(hour(), 24);
time.tm_min = to_nonnegative_int(minute(), 60);
time.tm_sec = to_nonnegative_int(second(), 60);
return time;
}

Expand All @@ -577,7 +594,8 @@ struct chrono_formatter {
write_sign();
if (isnan(value)) return write_nan();
typedef typename int_traits<int>::main_type main_type;
main_type n = to_unsigned(to_int(value));
main_type n = to_unsigned(
to_nonnegative_int(value, (std::numeric_limits<int>::max)()));
int num_digits = internal::count_digits(n);
if (width > num_digits) out = std::fill_n(out, width - num_digits, '0');
out = format_decimal<char_type>(out, n, num_digits);
Expand Down Expand Up @@ -624,7 +642,7 @@ struct chrono_formatter {

if (ns == numeric_system::standard) return write(hour(), 2);
auto time = tm();
time.tm_hour = to_int(hour());
time.tm_hour = to_nonnegative_int(hour(), 24);
format_localized(time, "%OH");
}

Expand All @@ -635,7 +653,7 @@ struct chrono_formatter {

if (ns == numeric_system::standard) return write(hour12(), 2);
auto time = tm();
time.tm_hour = to_int(hour12());
time.tm_hour = to_nonnegative_int(hour12(), 12);
format_localized(time, "%OI");
}

Expand All @@ -646,7 +664,7 @@ struct chrono_formatter {

if (ns == numeric_system::standard) return write(minute(), 2);
auto time = tm();
time.tm_min = to_int(minute());
time.tm_min = to_nonnegative_int(minute(), 60);
format_localized(time, "%OM");
}

Expand Down Expand Up @@ -679,7 +697,7 @@ struct chrono_formatter {
return;
}
auto time = tm();
time.tm_sec = to_int(second());
time.tm_sec = to_nonnegative_int(second(), 60);
format_localized(time, "%OS");
}

Expand Down
50 changes: 11 additions & 39 deletions include/fmt/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <cmath>
#include <cstdint>
#include <cstring>
#include <iterator>
#include <limits>
#include <memory>
#include <stdexcept>
Expand Down Expand Up @@ -94,10 +95,6 @@
# endif
#endif

#if FMT_SECURE_SCL
# include <iterator>
#endif

#ifdef __has_builtin
# define FMT_HAS_BUILTIN(x) __has_builtin(x)
#else
Expand Down Expand Up @@ -268,32 +265,9 @@ inline Dest bit_cast(const Source& source) {
return dest;
}

// An implementation of begin and end for pre-C++11 compilers such as gcc 4.
template <typename C>
FMT_CONSTEXPR auto begin(const C& c) -> decltype(c.begin()) {
return c.begin();
}
template <typename T, std::size_t N>
FMT_CONSTEXPR T* begin(T (&array)[N]) FMT_NOEXCEPT {
return array;
}
template <typename C> FMT_CONSTEXPR auto end(const C& c) -> decltype(c.end()) {
return c.end();
}
template <typename T, std::size_t N>
FMT_CONSTEXPR T* end(T (&array)[N]) FMT_NOEXCEPT {
return array + N;
}

// An implementation of iterator_t for pre-C++20 compilers such as gcc 4.
template <typename T> struct iterator_t {
typedef decltype(internal::begin(std::declval<const T&>())) type;
};

// For std::result_of in gcc 4.4.
template <typename Result> struct function {
template <typename T> struct result { typedef Result type; };
};
// An implementation of iterator_t for pre-C++20 systems.
template <typename T>
using iterator_t = decltype(std::begin(std::declval<T&>()));

template <typename Allocator>
typename Allocator::value_type* allocate(Allocator& alloc, std::size_t n) {
Expand Down Expand Up @@ -1545,7 +1519,7 @@ FMT_CONSTEXPR unsigned parse_nonnegative_int(const Char*& begin,
return value;
}

template <typename Context> class custom_formatter : public function<bool> {
template <typename Context> class custom_formatter {
private:
typedef typename Context::char_type char_type;

Expand All @@ -1572,8 +1546,7 @@ template <typename T> struct is_integer {
};
};

template <typename ErrorHandler>
class width_checker : public function<unsigned long long> {
template <typename ErrorHandler> class width_checker {
public:
explicit FMT_CONSTEXPR width_checker(ErrorHandler& eh) : handler_(eh) {}

Expand All @@ -1593,8 +1566,7 @@ class width_checker : public function<unsigned long long> {
ErrorHandler& handler_;
};

template <typename ErrorHandler>
class precision_checker : public function<unsigned long long> {
template <typename ErrorHandler> class precision_checker {
public:
explicit FMT_CONSTEXPR precision_checker(ErrorHandler& eh) : handler_(eh) {}

Expand Down Expand Up @@ -3351,15 +3323,15 @@ arg_join<It, wchar_t> join(It begin, It end, wstring_view sep) {
\endrst
*/
template <typename Range>
arg_join<typename internal::iterator_t<Range>::type, char> join(
arg_join<internal::iterator_t<const Range>, char> join(
const Range& range, string_view sep) {
return join(internal::begin(range), internal::end(range), sep);
return join(std::begin(range), std::end(range), sep);
}

template <typename Range>
arg_join<typename internal::iterator_t<Range>::type, wchar_t> join(
arg_join<internal::iterator_t<const Range>, wchar_t> join(
const Range& range, wstring_view sep) {
return join(internal::begin(range), internal::end(range), sep);
return join(std::begin(range), std::end(range), sep);
}
#endif

Expand Down
12 changes: 5 additions & 7 deletions include/fmt/printf.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ template <> struct int_checker<true> {
static bool fits_in_int(int) { return true; }
};

class printf_precision_handler : public function<int> {
class printf_precision_handler {
public:
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
int operator()(T value) {
Expand All @@ -55,7 +55,7 @@ class printf_precision_handler : public function<int> {
};

// An argument visitor that returns true iff arg is a zero integer.
class is_zero_int : public function<bool> {
class is_zero_int {
public:
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
bool operator()(T value) {
Expand All @@ -72,8 +72,7 @@ template <typename T> struct make_unsigned_or_bool : std::make_unsigned<T> {};

template <> struct make_unsigned_or_bool<bool> { typedef bool type; };

template <typename T, typename Context>
class arg_converter : public function<void> {
template <typename T, typename Context> class arg_converter {
private:
typedef typename Context::char_type Char;

Expand Down Expand Up @@ -129,7 +128,7 @@ void convert_arg(basic_format_arg<Context>& arg, Char type) {
}

// Converts an integer argument to char for printf.
template <typename Context> class char_converter : public function<void> {
template <typename Context> class char_converter {
private:
basic_format_arg<Context>& arg_;

Expand All @@ -148,8 +147,7 @@ template <typename Context> class char_converter : public function<void> {

// Checks if an argument is a valid printf width specifier and sets
// left alignment if it is negative.
template <typename Char>
class printf_width_handler : public function<unsigned> {
template <typename Char> class printf_width_handler {
private:
typedef basic_format_specs<Char> format_specs;

Expand Down
4 changes: 1 addition & 3 deletions test/format
Original file line number Diff line number Diff line change
Expand Up @@ -489,9 +489,7 @@ namespace detail {

template <typename Range>
class arg_formatter
: public fmt::internal::function<
typename fmt::internal::arg_formatter_base<Range, error_handler>::iterator>,
public fmt::internal::arg_formatter_base<Range, error_handler> {
: public fmt::internal::arg_formatter_base<Range, error_handler> {
private:
using char_type = typename Range::value_type;
using base = fmt::internal::arg_formatter_base<Range, error_handler>;
Expand Down
4 changes: 2 additions & 2 deletions test/format-impl-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ TEST(FPTest, GrisuFormatCompilesWithNonIEEEDouble) {
grisu_format(4.2f, buf, -1, false, exp);
}

template <typename T> struct ValueExtractor : fmt::internal::function<T> {
template <typename T> struct value_extractor {
T operator()(T value) { return value; }

template <typename U> FMT_NORETURN T operator()(U) {
Expand All @@ -157,7 +157,7 @@ TEST(FormatTest, ArgConverter) {
fmt::visit_format_arg(
fmt::internal::arg_converter<long long, fmt::format_context>(arg, 'd'),
arg);
EXPECT_EQ(value, fmt::visit_format_arg(ValueExtractor<long long>(), arg));
EXPECT_EQ(value, fmt::visit_format_arg(value_extractor<long long>(), arg));
}

TEST(FormatTest, FormatNegativeNaN) {
Expand Down
4 changes: 1 addition & 3 deletions test/format-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1890,9 +1890,7 @@ TEST(FormatTest, FixedEnum) { EXPECT_EQ("0", fmt::format("{}", B)); }
typedef fmt::back_insert_range<fmt::internal::buffer<char>> buffer_range;

class mock_arg_formatter
: public fmt::internal::function<
fmt::internal::arg_formatter_base<buffer_range>::iterator>,
public fmt::internal::arg_formatter_base<buffer_range> {
: public fmt::internal::arg_formatter_base<buffer_range> {
private:
MOCK_METHOD1(call, void(long long value));

Expand Down

0 comments on commit 9a3f4cf

Please sign in to comment.