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).

Reply via email to