Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean-up sign-conversion warnings #1435

Closed
wants to merge 8 commits into from

Conversation

0x8000-0000
Copy link
Contributor

I agree that my contributions are licensed under the {fmt} license, and agree to future changes to the licensing.

@0x8000-0000
Copy link
Contributor Author

This first step reduces the number of -Wsign-conversion warnings from 317 to 58 with GCC9.

@0x8000-0000
Copy link
Contributor Author

I have tried to reproduce the test crash on Visual Studio 2019 building in Release Mode for 32 bits (I don't have 2017)

> "C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\Common7\Tools\VsDevCmd.bat" -arch=x86

> cmake ..\fmt -DFMT_PEDANTIC=ON -DCMAKE_BUILD_TYPE=Release -G"Visual Studio 16 2019"

> cmake --build . --config Release

> ctest -C Release

And I can't reproduce the crash. If somebody has access to that toolchain and could try debugging it, I would be very grateful. Otherwise I would have to do a binary search on all the changes in this commit :(

@0x8000-0000
Copy link
Contributor Author

Made doubly-sure I have produced 32 bit binaries with:

"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake" ..\fmt -DFMT_PEDANTIC=ON -DCMAKE_BUILD_TYPE=Release -A win32

$ file bin/Release/color-test.exe
bin/Release/color-test.exe: PE32 executable (console) Intel 80386, for MS Windows

Still, no crash when running the 32-bit binary on Windows 64, running on AMD laptop (FWIW)

@0x8000-0000 0x8000-0000 force-pushed the no-no-sign-conversion branch 5 times, most recently from fecb9d4 to 3adf8e6 Compare November 30, 2019 03:56
@0x8000-0000
Copy link
Contributor Author

0x8000-0000 commented Nov 30, 2019

This still crashes in UtilTest.WriteUIntPtr, even with just some changes in chrono.h ! I suspect the master branch just fails in the same way at this time.

@vitaut can you please try kicking a regression off master branch and see if it fails on Windows / 32bit Release with Visual Studio 2017?

@0x8000-0000
Copy link
Contributor Author

Oh, it "fails" in the same way as #1438 , even though that one just modifies a text document.

@vitaut
Copy link
Contributor

vitaut commented Nov 30, 2019

Yeah, WriteUIntPtr test failure is unrelated. I'm about to fix it (just waiting for see if CI is green).

@vitaut
Copy link
Contributor

vitaut commented Nov 30, 2019

Merged the fix into master. Please rebase.

@0x8000-0000 0x8000-0000 force-pushed the no-no-sign-conversion branch 2 times, most recently from 51b084d to afcc766 Compare November 30, 2019 19:45
@0x8000-0000
Copy link
Contributor Author

Down to 51 errors on GCC9, 18 on Clang9.

@0x8000-0000 0x8000-0000 force-pushed the no-no-sign-conversion branch 3 times, most recently from 3d0ed93 to f812507 Compare November 30, 2019 21:26
@0x8000-0000
Copy link
Contributor Author

Down to 1 warning in fmt code, reported by both Gcc9 and Clang9.

fmt/test/format-test.cc:2026:10: error: implicit conversion changes signedness: 'unsigned __int128' to '::testing::internal::Function<void (__int128_t)>::Argument1' (aka '__int128') [-Werror,-Wsign-conversion]

Gcc9 also reports several warnings stemming from a macro in test/gtest/gtest.h:

1922 #define GTEST_COMPILE_ASSERT_(expr, msg) \
1923 typedef ::testing::internal::CompileAssert<(static_cast(expr))> \
1924 msg[static_cast(expr) ? 1 : -1] GTEST_ATTRIBUTE_UNUSED_

I think there are some cases where Gcc9 sees "msg[-1]" and reports the warning. It might be worth exploring whether upgrading gtest/gmock would clean that up.

@0x8000-0000 0x8000-0000 force-pushed the no-no-sign-conversion branch from f812507 to 18e9508 Compare November 30, 2019 22:08
Copy link
Contributor

@vitaut vitaut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR.

include/fmt/chrono.h Show resolved Hide resolved
include/fmt/compile.h Outdated Show resolved Hide resolved
include/fmt/format-inl.h Outdated Show resolved Hide resolved
include/fmt/format-inl.h Show resolved Hide resolved
include/fmt/format.h Outdated Show resolved Hide resolved
include/fmt/printf.h Outdated Show resolved Hide resolved
test/format-impl-test.cc Outdated Show resolved Hide resolved
Comment on lines -2008 to +2012
MOCK_METHOD1(call, void(__int128_t value));
MOCK_METHOD1(callSigned, void(__int128_t value));
MOCK_METHOD1(callUnsigned, void(__uint128_t value));
#else
MOCK_METHOD1(call, void(long long value));
MOCK_METHOD1(callSigned, void(long long value));
MOCK_METHOD1(callUnsigned, void(unsigned long long value));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unnecessary for the test purposes. Just static cast to the largest signed type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test is calling the mocked method with both signed and unsigned values.

I don't care as much about the tests being -Wsign-conversion clean, but...

I want my own code to be -Wsign-conversion clean, because we got bitten in the past by (unsigned)-1, and other bit fields confusion (somebody shoving 32 bits into a 16 bit register) and I want to use {fmt}. Which means {fmt} needs to be -Wsign-conversion clean, which means its test suite needs to be -Wsign-conversion clean, otherwise we can't enforce it via the automated regression suite.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a simple mock which is only used here:

TEST(FormatTest, CustomArgFormatter) { custom_format("{}", 42); }

so casting is fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed as suggested and I got back the dreaded:

fmt/test/format-test.cc:2026:10: error: implicit conversion changes signedness: 'unsigned __int128' to '::testing::internal::Function<void (__int128_t)>::Argument1' (aka '__int128') [-Werror,-Wsign-conversion]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the long story, threaded through format.h and core.h:

/home/florin/libraries/fmt/test/format-test.cc: In instantiation of ‘typename std::enable_if<fmt::v6::internal::is_integral::value, std::back_insert_iterator<fmt::v6::internal::buffer > >::type mock_arg_formatter::operator()(T) [with T = __int128 unsigned; typename std::enable_if<fmt::v6::internal::is_integral::value, std::back_insert_iterator<fmt::v6::internal::buffer > >::type = std::back_insert_iterator<fmt::v6::internal::buffer >]’:

/home/florin/libraries/fmt/include/fmt/core.h:1024:15: required from ‘constexpr decltype (vis(0)) fmt::v6::visit_format_arg(Visitor&&, const fmt::v6::basic_format_arg&) [with Visitor = mock_arg_formatter; Context = fmt::v6::basic_format_context<std::back_insert_iterator<fmt::v6::internal::buffer >, char>; decltype (vis(0)) = std::back_insert_iterator<fmt::v6::internal::buffer >]’

/home/florin/libraries/fmt/include/fmt/format.h:3172:25: required from ‘void fmt::v6::format_handler<ArgFormatter, Char, Context>::on_replacement_field(const Char*) [with ArgFormatter = mock_arg_formatter; Char = char; Context = fmt::v6::basic_format_context<std::back_insert_iterator<fmt::v6::internal::buffer >, char>]’

/home/florin/libraries/fmt/include/fmt/format.h:2583:7: required from ‘constexpr void fmt::v6::internal::parse_format_string(fmt::v6::basic_string_view, Handler&&) [with bool IS_CONSTEXPR = false; Char = char; Handler = fmt::v6::format_handler<mock_arg_formatter, char, fmt::v6::basic_format_context<std::back_insert_iterator<fmt::v6::internal::buffer >, char> >&]’

/home/florin/libraries/fmt/include/fmt/format.h:3205:39: required from ‘typename Context::iterator fmt::v6::vformat_to(typename ArgFormatter::range, fmt::v6::basic_string_view, fmt::v6::basic_format_args, fmt::v6::internal::locale_ref) [with ArgFormatter = mock_arg_formatter; Char = char; Context = fmt::v6::basic_format_context<std::back_insert_iterator<fmt::v6::internal::buffer >, char>; typename Context::iterator = std::back_insert_iterator<fmt::v6::internal::buffer >; typename ArgFormatter::range = fmt::v6::buffer_range]’

/home/florin/libraries/fmt/test/format-test.cc:2043:63: required from here
/home/florin/libraries/fmt/test/format-test.cc:2026:10: error: conversion to ‘testing::internal::Function<void(__int128)>::Argument1’ {aka ‘__int128’} from ‘__int128 unsigned’ may change the sign of the result [-Werror=sign-conversion]
2026 | call(value);
| ^~~~~

test/printf-test.cc Show resolved Hide resolved
width_arg_id = c - '0';
width_arg_id = static_cast<size_t>(c - '0');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tests an example from the standard and should remain unchanged.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should width_arg_id become signed then?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

width_arg_id is passed on the next line to check_arg_id which requires a size_t .

@0x8000-0000
Copy link
Contributor Author

Once this is approved I can refactor the top commit and push the changes into the earlier commits. I didn't want to force-push during the review.

@0x8000-0000 0x8000-0000 force-pushed the no-no-sign-conversion branch 2 times, most recently from fdedf0d to 44ed940 Compare December 1, 2019 18:16
@vitaut
Copy link
Contributor

vitaut commented Dec 5, 2019

I guess this can be closed now in favor of #1440.

@vitaut vitaut closed this Dec 5, 2019
@0x8000-0000 0x8000-0000 deleted the no-no-sign-conversion branch November 25, 2021 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants