From: Jiri Slaby > Sent: 26 October 2022 08:18 > > On 24. 10. 22, 21:01, Martin Liška wrote: > > Starting with GCC 13, since > > [g3b3083a598ca3f4b] c: C2x enums wider than int [PR36113] > > > > GCC promotes enum values with larger than integer types to a wider type. > > In case of the anonymous enum type in blk-iocost.c it is: > > > > enum { > > MILLION = 1000000, > > ... > > > > WEIGHT_ONE = 1 << 16, > > ... > > VTIME_PER_SEC_SHIFT = 37, > > VTIME_PER_SEC = 1LLU << VTIME_PER_SEC_SHIFT, > > ... > > > > as seen VTIME_PER_SEC cannot fit into 32-bits (int type), thus one needs > > to use 'long unsigned int' in the format string. > > > > It fixes then the following 2 warnings: > > > > block/blk-iocost.c: In function ‘ioc_weight_prfill’: > > block/blk-iocost.c:3035:37: error: format ‘%u’ expects argument of type ‘unsigned int’, but argument > 4 has type ‘long unsigned int’ [-Werror=format=] > > 3035 | seq_printf(sf, "%s %u\n", dname, iocg->cfg_weight / WEIGHT_ONE); > > | ~^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > | | | > > | unsigned int long unsigned int > > | %lu > > block/blk-iocost.c: In function ‘ioc_weight_show’: > > block/blk-iocost.c:3045:34: error: format ‘%u’ expects argument of type ‘unsigned int’, but argument > 3 has type ‘long unsigned int’ [-Werror=format=] > > 3045 | seq_printf(sf, "default %u\n", iocc->dfl_weight / WEIGHT_ONE); > > | ~^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > | | | > > | unsigned int long unsigned int > > | %lu > > But introduces two with gcc-12 ;): > > block/blk-iocost.c: In function ‘ioc_weight_prfill’: > > block/blk-iocost.c:3037:38: error: format ‘%lu’ expects argument of > type ‘long unsigned int’, but argument 4 has type ‘u32’ {aka ‘unsigned > int’} [-Werror=format=] > > 3037 | seq_printf(sf, "%s %lu\n", dname, > iocg->cfg_weight / WEIGHT_ONE); > > | ~~^ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > | | > | > > | long unsigned int > u32 {aka unsigned int} > > | %u > > > Note that: > 1) the specs says enum behaves as int, or uint in some cases > 2) iocc->dfl_weight is u32, i.e. uint > WEIGHT_ONE is 1 << 16, i.e. int > so the promotion should be to s32/int. Or not? > > I think gcc-13 is wrong -- incosistent with gcc-12 at least. The presence of VTIME_PER_SEC in the enum forces the enum to 64bits (this must be a gcc extension). The change in gcc 13 seems to be that the types of all the enum values are now (probably correctly) that of the enum. So WEIGHT_ONE changes from 'unsigned int' to 'unsigned long'. See: https://godbolt.org/z/6K4PoK9sv David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)