From a07627b1f8c4f11a22689619874e241a611e5805 Mon Sep 17 00:00:00 2001 From: Jonathan Gopel Date: Wed, 11 Nov 2020 08:57:52 -0700 Subject: [PATCH] :bug: Implicit sign conversion warning in clang in c++17 and 20 modes (#2009) Problem: - On Apple clang version 11.0.3 (clang-1103.0.32.62) in C++17 and C++20 mode, clang 11.0.0 in C++17 and C++20 mode, and clang 9.0.1 in C++17 mode, the following error is generated: In file included from test/compile-test.cc:16: include/fmt/compile.h:518:25: error: implicit conversion changes signedness: 'long' to 'unsigned long' [-Werror,-Wsign-conversion] return {f, pos + (end - str.data()) + 1, ctx.next_arg_id()}; ~ ~~~~^~~~~~~~~~~~ include/fmt/compile.h:538:31: note: in instantiation of function template specialization 'fmt::v7::detail::parse_specs' requested here constexpr auto result = parse_specs(str, POS + 2, ID); ^ include/fmt/compile.h:569:17: note: in instantiation of function template specialization 'fmt::v7::detail::compile_format_string, 0, 0, FMT_COMPILE_STRING>' requested here detail::compile_format_string, 0, 0>( ^ include/fmt/compile.h:648:37: note: in instantiation of function template specialization 'fmt::v7::detail::compile' requested here constexpr auto compiled = detail::compile(S()); ^ test/compile-test.cc:140:24: note: in instantiation of function template specialization 'fmt::v7::format' requested here EXPECT_EQ("42", fmt::format(FMT_COMPILE("{:x}"), 0x42)); ^ In file included from test/compile-test.cc:16: include/fmt/compile.h:518:25: error: implicit conversion changes signedness: 'long' to 'unsigned long' [-Werror,-Wsign-conversion] return {f, pos + (end - str.data()) + 1, ctx.next_arg_id()}; ~ ~~~~^~~~~~~~~~~~ include/fmt/compile.h:538:31: note: in instantiation of function template specialization 'fmt::v7::detail::parse_specs' requested here constexpr auto result = parse_specs(str, POS + 2, ID); ^ include/fmt/compile.h:494:27: note: in instantiation of function template specialization 'fmt::v7::detail::compile_format_string, 5, 2, FMT_COMPILE_STRING>' requested here constexpr auto tail = compile_format_string(format_str); ^ include/fmt/compile.h:539:14: note: in instantiation of function template specialization 'fmt::v7::detail::parse_tail, 5, 2, fmt::v7::detail::spec_field, FMT_COMPILE_STRING>' requested here return parse_tail( ^ include/fmt/compile.h:569:17: note: in instantiation of function template specialization 'fmt::v7::detail::compile_format_string, 0, 0, FMT_COMPILE_STRING>' requested here detail::compile_format_string, 0, 0>( ^ include/fmt/compile.h:648:37: note: in instantiation of function template specialization 'fmt::v7::detail::compile' requested here constexpr auto compiled = detail::compile(S()); ^ test/compile-test.cc:145:18: note: in instantiation of function template specialization 'fmt::v7::format' requested here fmt::format(FMT_COMPILE("{:{}}{:{}}"), 42, 4, "foo", 5)); ^ 2 errors generated. Solution: - Explicitly cast the result of the subtraction to the (unsigned) outer type. Co-authored-by: Jonathan Gopel --- include/fmt/compile.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/fmt/compile.h b/include/fmt/compile.h index db562ce406eb..d48fc352725e 100644 --- a/include/fmt/compile.h +++ b/include/fmt/compile.h @@ -515,7 +515,8 @@ constexpr parse_specs_result parse_specs(basic_string_view str, auto ctx = basic_format_parse_context(str, {}, arg_id + 1); auto f = formatter(); auto end = f.parse(ctx); - return {f, pos + (end - str.data()) + 1, ctx.next_arg_id()}; + return {f, pos + fmt::detail::to_unsigned(end - str.data()) + 1, + ctx.next_arg_id()}; } // Compiles a non-empty format string and returns the compiled representation