2022-10-24 22:29:50

by Martin Liška

[permalink] [raw]
Subject: [PATCH] block: fix Werror=format with GCC 13

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

Signed-off-by: Martin Liska <[email protected]>
---
block/blk-iocost.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/block/blk-iocost.c b/block/blk-iocost.c
index 495396425bad..f165bac9bffb 100644
--- a/block/blk-iocost.c
+++ b/block/blk-iocost.c
@@ -3032,7 +3032,7 @@ static u64 ioc_weight_prfill(struct seq_file *sf, struct blkg_policy_data *pd,
struct ioc_gq *iocg = pd_to_iocg(pd);

if (dname && iocg->cfg_weight)
- seq_printf(sf, "%s %u\n", dname, iocg->cfg_weight / WEIGHT_ONE);
+ seq_printf(sf, "%s %lu\n", dname, iocg->cfg_weight / WEIGHT_ONE);
return 0;
}

@@ -3042,7 +3042,7 @@ static int ioc_weight_show(struct seq_file *sf, void *v)
struct blkcg *blkcg = css_to_blkcg(seq_css(sf));
struct ioc_cgrp *iocc = blkcg_to_iocc(blkcg);

- seq_printf(sf, "default %u\n", iocc->dfl_weight / WEIGHT_ONE);
+ seq_printf(sf, "default %lu\n", iocc->dfl_weight / WEIGHT_ONE);
blkcg_print_blkgs(sf, blkcg, ioc_weight_prfill,
&blkcg_policy_iocost, seq_cft(sf)->private, false);
return 0;
--
2.38.0


2022-10-26 07:40:39

by Jiri Slaby

[permalink] [raw]
Subject: Re: [PATCH] block: fix Werror=format with GCC 13

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.

> Signed-off-by: Martin Liska <[email protected]>
> ---
> block/blk-iocost.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/block/blk-iocost.c b/block/blk-iocost.c
> index 495396425bad..f165bac9bffb 100644
> --- a/block/blk-iocost.c
> +++ b/block/blk-iocost.c
> @@ -3032,7 +3032,7 @@ static u64 ioc_weight_prfill(struct seq_file *sf, struct blkg_policy_data *pd,
> struct ioc_gq *iocg = pd_to_iocg(pd);
>
> if (dname && iocg->cfg_weight)
> - seq_printf(sf, "%s %u\n", dname, iocg->cfg_weight / WEIGHT_ONE);
> + seq_printf(sf, "%s %lu\n", dname, iocg->cfg_weight / WEIGHT_ONE);
> return 0;
> }
>
> @@ -3042,7 +3042,7 @@ static int ioc_weight_show(struct seq_file *sf, void *v)
> struct blkcg *blkcg = css_to_blkcg(seq_css(sf));
> struct ioc_cgrp *iocc = blkcg_to_iocc(blkcg);
>
> - seq_printf(sf, "default %u\n", iocc->dfl_weight / WEIGHT_ONE);
> + seq_printf(sf, "default %lu\n", iocc->dfl_weight / WEIGHT_ONE);
> blkcg_print_blkgs(sf, blkcg, ioc_weight_prfill,
> &blkcg_policy_iocost, seq_cft(sf)->private, false);
> return 0;

thanks,
--
js
suse labs


2022-10-26 08:25:31

by David Laight

[permalink] [raw]
Subject: RE: [PATCH] block: fix Werror=format with GCC 13

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)

2022-10-26 20:37:36

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] block: fix Werror=format with GCC 13

Hi Martin,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on axboe-block/for-next]
[also build test WARNING on linus/master v6.1-rc2 next-20221026]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Martin-Li-ka/block-fix-Werror-format-with-GCC-13/20221025-045756
base: https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git for-next
patch link: https://lore.kernel.org/r/f70c7a11-e81e-f6b9-a403-315117f4aa3a%40suse.cz
patch subject: [PATCH] block: fix Werror=format with GCC 13
config: x86_64-randconfig-a012
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/f341dda9dc3f582b49fcf0ef0b5aa24e975ccc43
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Martin-Li-ka/block-fix-Werror-format-with-GCC-13/20221025-045756
git checkout f341dda9dc3f582b49fcf0ef0b5aa24e975ccc43
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

>> block/blk-iocost.c:3037:37: warning: format specifies type 'unsigned long' but the argument has type 'unsigned int' [-Wformat]
seq_printf(sf, "%s %lu\n", dname, iocg->cfg_weight / WEIGHT_ONE);
~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
%u
block/blk-iocost.c:3047:34: warning: format specifies type 'unsigned long' but the argument has type 'unsigned int' [-Wformat]
seq_printf(sf, "default %lu\n", iocc->dfl_weight / WEIGHT_ONE);
~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
%u
2 warnings generated.


vim +3037 block/blk-iocost.c

3029
3030 static u64 ioc_weight_prfill(struct seq_file *sf, struct blkg_policy_data *pd,
3031 int off)
3032 {
3033 const char *dname = blkg_dev_name(pd->blkg);
3034 struct ioc_gq *iocg = pd_to_iocg(pd);
3035
3036 if (dname && iocg->cfg_weight)
> 3037 seq_printf(sf, "%s %lu\n", dname, iocg->cfg_weight / WEIGHT_ONE);
3038 return 0;
3039 }
3040

--
0-DAY CI Kernel Test Service
https://01.org/lkp


Attachments:
(No filename) (2.90 kB)
config (167.58 kB)
Download all attachments