https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113051
Bug ID: 113051 Summary: -Wformat-signedness wrongly triggers for values from template arguments Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: adam.f.badura at gmail dot com Target Milestone: --- Consider sample code (https://godbolt.org/z/7T3vGefEq): ``` #include <cinttypes> #include <cstdio> template<std::uint8_t i> auto foo() { return std::printf("%u\n", i); } auto bar(std::uint8_t i) { return std::printf("%u\n", i); } void test() { foo<11>(); bar(11); } ``` When compiled with ``` -std=c++17 -Wformat=1 -Wformat-signedness ``` on GCC 10.2 (where I detected it) and GCC trunk (as on Compiler Explorer from the link) I'm getting the following warning: ``` <source>: In instantiation of 'auto foo() [with unsigned char i = 11]': <source>:17:10: required from here 17 | foo<11>(); | ~~~~~~~^~ <source>:7:24: warning: format '%u' expects argument of type 'unsigned int', but argument 2 has type 'int' [-Wformat=] 7 | return std::printf("%u\n", i); | ~^ | | | unsigned int | %u ``` The warning is not reported in `bar` but is reported in `foo` where the argument comes from the template. As an attempt to work around the problem I have tried to explicitly force the type of `i` in `foo` to `std::uint8_t` (https://godbolt.org/z/eK5TTx93o) and `std::uint16_t` (https://godbolt.org/z/rqY6n58n8), but it didn't help. Only forcing `std::uint32_t` helped (https://godbolt.org/z/j7MY7YTeG).