[next,resend,2/5] minmax: Allow min()/max()/clamp() if the arguments have the same signedness.

Message ID a09512c8526b46759669d0b879144563@AcuMS.aculab.com
State New
Headers
Series minmax: Relax type checks in min() and max(). |

Commit Message

David Laight July 25, 2023, 11:51 a.m. UTC
  The type-check in min()/max() is there to stop unexpected results if a
negative value gets converted to a large unsigned value.
However it also rejects 'unsigned int' v 'unsigned long' compares
which are common and never problematc.

Replace the 'same type' check with a 'same signedness' check.

The new test isn't itself a compile time error, so use static_assert()
to report the error and give a meaningful error message.

Due to the way builtin_choose_expr() works detecting the error in the
'non-constant' side (where static_assert() can be used) also detects
errors when the arguments are constant.

Signed-off-by: David Laight <david.laight@aculab.com>
---

resend as response to 0/5

 include/linux/minmax.h | 61 +++++++++++++++++++-----------------------
 1 file changed, 28 insertions(+), 33 deletions(-)
  

Comments

kernel test robot July 25, 2023, 6:02 p.m. UTC | #1
Hi David,

kernel test robot noticed the following build errors:

[auto build test ERROR on akpm-mm/mm-everything]
[also build test ERROR on linus/master v6.5-rc3 next-20230725]
[cannot apply to next-20230725]
[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/David-Laight/minmax-Allow-min-max-clamp-if-the-arguments-have-the-same-signedness/20230725-204940
base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link:    https://lore.kernel.org/r/a09512c8526b46759669d0b879144563%40AcuMS.aculab.com
patch subject: [PATCH next resend 2/5] minmax: Allow min()/max()/clamp() if the arguments have the same signedness.
config: riscv-randconfig-r024-20230725 (https://download.01.org/0day-ci/archive/20230726/202307260144.boYg18Ty-lkp@intel.com/config)
compiler: riscv32-linux-gcc (GCC) 12.3.0
reproduce: (https://download.01.org/0day-ci/archive/20230726/202307260144.boYg18Ty-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202307260144.boYg18Ty-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/irqchip/irq-meson-gpio.c:15:
>> include/linux/irqchip.h:24:10: error: implicit declaration of function '__typecheck'; did you mean 'typecheck'? [-Werror=implicit-function-declaration]
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |          ^~~~~~~~~~~
   include/linux/irqchip.h:45:45: note: in expansion of macro 'typecheck_irq_init_cb'
      45 |                                     .data = typecheck_irq_init_cb(fn), },
         |                                             ^~~~~~~~~~~~~~~~~~~~~
   drivers/irqchip/irq-meson-gpio.c:597:1: note: in expansion of macro 'IRQCHIP_MATCH'
     597 | IRQCHIP_MATCH("amlogic,meson-gpio-intc", meson_gpio_irq_of_init)
         | ^~~~~~~~~~~~~
>> include/linux/irqchip.h:24:9: error: initializer element is not constant
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |         ^
   include/linux/irqchip.h:45:45: note: in expansion of macro 'typecheck_irq_init_cb'
      45 |                                     .data = typecheck_irq_init_cb(fn), },
         |                                             ^~~~~~~~~~~~~~~~~~~~~
   drivers/irqchip/irq-meson-gpio.c:597:1: note: in expansion of macro 'IRQCHIP_MATCH'
     597 | IRQCHIP_MATCH("amlogic,meson-gpio-intc", meson_gpio_irq_of_init)
         | ^~~~~~~~~~~~~
   include/linux/irqchip.h:24:9: note: (near initialization for 'meson_gpio_intc_irqchip_match_table[0].data')
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |         ^
   include/linux/irqchip.h:45:45: note: in expansion of macro 'typecheck_irq_init_cb'
      45 |                                     .data = typecheck_irq_init_cb(fn), },
         |                                             ^~~~~~~~~~~~~~~~~~~~~
   drivers/irqchip/irq-meson-gpio.c:597:1: note: in expansion of macro 'IRQCHIP_MATCH'
     597 | IRQCHIP_MATCH("amlogic,meson-gpio-intc", meson_gpio_irq_of_init)
         | ^~~~~~~~~~~~~
   cc1: some warnings being treated as errors
--
   In file included from include/linux/irqchip.h:16,
                    from drivers/irqchip/irq-riscv-intc.c:14:
>> include/linux/irqchip.h:24:10: error: implicit declaration of function '__typecheck'; did you mean 'typecheck'? [-Werror=implicit-function-declaration]
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |          ^~~~~~~~~~~
   include/linux/of.h:1478:31: note: in definition of macro '_OF_DECLARE'
    1478 |                      .data = (fn == (fn_type)NULL) ? fn : fn  }
         |                               ^~
   include/linux/irqchip.h:37:9: note: in expansion of macro 'OF_DECLARE_2'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |         ^~~~~~~~~~~~
   include/linux/irqchip.h:37:45: note: in expansion of macro 'typecheck_irq_init_cb'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |                                             ^~~~~~~~~~~~~~~~~~~~~
   drivers/irqchip/irq-riscv-intc.c:164:1: note: in expansion of macro 'IRQCHIP_DECLARE'
     164 | IRQCHIP_DECLARE(riscv, "riscv,cpu-intc", riscv_intc_init);
         | ^~~~~~~~~~~~~~~
>> include/linux/of.h:1478:30: error: initializer element is not constant
    1478 |                      .data = (fn == (fn_type)NULL) ? fn : fn  }
         |                              ^
   include/linux/of.h:1493:17: note: in expansion of macro '_OF_DECLARE'
    1493 |                 _OF_DECLARE(table, name, compat, fn, of_init_fn_2)
         |                 ^~~~~~~~~~~
   include/linux/irqchip.h:37:9: note: in expansion of macro 'OF_DECLARE_2'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |         ^~~~~~~~~~~~
   drivers/irqchip/irq-riscv-intc.c:164:1: note: in expansion of macro 'IRQCHIP_DECLARE'
     164 | IRQCHIP_DECLARE(riscv, "riscv,cpu-intc", riscv_intc_init);
         | ^~~~~~~~~~~~~~~
   include/linux/of.h:1478:30: note: (near initialization for '__of_table_riscv.data')
    1478 |                      .data = (fn == (fn_type)NULL) ? fn : fn  }
         |                              ^
   include/linux/of.h:1493:17: note: in expansion of macro '_OF_DECLARE'
    1493 |                 _OF_DECLARE(table, name, compat, fn, of_init_fn_2)
         |                 ^~~~~~~~~~~
   include/linux/irqchip.h:37:9: note: in expansion of macro 'OF_DECLARE_2'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |         ^~~~~~~~~~~~
   drivers/irqchip/irq-riscv-intc.c:164:1: note: in expansion of macro 'IRQCHIP_DECLARE'
     164 | IRQCHIP_DECLARE(riscv, "riscv,cpu-intc", riscv_intc_init);
         | ^~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors
--
   In file included from drivers/irqchip/irq-renesas-rzg2l.c:14:
>> include/linux/irqchip.h:24:10: error: implicit declaration of function '__typecheck'; did you mean 'typecheck'? [-Werror=implicit-function-declaration]
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |          ^~~~~~~~~~~
   include/linux/irqchip.h:45:45: note: in expansion of macro 'typecheck_irq_init_cb'
      45 |                                     .data = typecheck_irq_init_cb(fn), },
         |                                             ^~~~~~~~~~~~~~~~~~~~~
   drivers/irqchip/irq-renesas-rzg2l.c:389:1: note: in expansion of macro 'IRQCHIP_MATCH'
     389 | IRQCHIP_MATCH("renesas,rzg2l-irqc", rzg2l_irqc_init)
         | ^~~~~~~~~~~~~
>> include/linux/irqchip.h:24:9: error: initializer element is not constant
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |         ^
   include/linux/irqchip.h:45:45: note: in expansion of macro 'typecheck_irq_init_cb'
      45 |                                     .data = typecheck_irq_init_cb(fn), },
         |                                             ^~~~~~~~~~~~~~~~~~~~~
   drivers/irqchip/irq-renesas-rzg2l.c:389:1: note: in expansion of macro 'IRQCHIP_MATCH'
     389 | IRQCHIP_MATCH("renesas,rzg2l-irqc", rzg2l_irqc_init)
         | ^~~~~~~~~~~~~
   include/linux/irqchip.h:24:9: note: (near initialization for 'rzg2l_irqc_irqchip_match_table[0].data')
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |         ^
   include/linux/irqchip.h:45:45: note: in expansion of macro 'typecheck_irq_init_cb'
      45 |                                     .data = typecheck_irq_init_cb(fn), },
         |                                             ^~~~~~~~~~~~~~~~~~~~~
   drivers/irqchip/irq-renesas-rzg2l.c:389:1: note: in expansion of macro 'IRQCHIP_MATCH'
     389 | IRQCHIP_MATCH("renesas,rzg2l-irqc", rzg2l_irqc_init)
         | ^~~~~~~~~~~~~
   cc1: some warnings being treated as errors
--
   In file included from include/linux/irqchip.h:16,
                    from drivers/irqchip/irq-sifive-plic.c:11:
>> include/linux/irqchip.h:24:10: error: implicit declaration of function '__typecheck'; did you mean 'typecheck'? [-Werror=implicit-function-declaration]
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |          ^~~~~~~~~~~
   include/linux/of.h:1478:31: note: in definition of macro '_OF_DECLARE'
    1478 |                      .data = (fn == (fn_type)NULL) ? fn : fn  }
         |                               ^~
   include/linux/irqchip.h:37:9: note: in expansion of macro 'OF_DECLARE_2'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |         ^~~~~~~~~~~~
   include/linux/irqchip.h:37:45: note: in expansion of macro 'typecheck_irq_init_cb'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |                                             ^~~~~~~~~~~~~~~~~~~~~
   drivers/irqchip/irq-sifive-plic.c:571:1: note: in expansion of macro 'IRQCHIP_DECLARE'
     571 | IRQCHIP_DECLARE(sifive_plic, "sifive,plic-1.0.0", plic_init);
         | ^~~~~~~~~~~~~~~
>> include/linux/of.h:1478:30: error: initializer element is not constant
    1478 |                      .data = (fn == (fn_type)NULL) ? fn : fn  }
         |                              ^
   include/linux/of.h:1493:17: note: in expansion of macro '_OF_DECLARE'
    1493 |                 _OF_DECLARE(table, name, compat, fn, of_init_fn_2)
         |                 ^~~~~~~~~~~
   include/linux/irqchip.h:37:9: note: in expansion of macro 'OF_DECLARE_2'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |         ^~~~~~~~~~~~
   drivers/irqchip/irq-sifive-plic.c:571:1: note: in expansion of macro 'IRQCHIP_DECLARE'
     571 | IRQCHIP_DECLARE(sifive_plic, "sifive,plic-1.0.0", plic_init);
         | ^~~~~~~~~~~~~~~
   include/linux/of.h:1478:30: note: (near initialization for '__of_table_sifive_plic.data')
    1478 |                      .data = (fn == (fn_type)NULL) ? fn : fn  }
         |                              ^
   include/linux/of.h:1493:17: note: in expansion of macro '_OF_DECLARE'
    1493 |                 _OF_DECLARE(table, name, compat, fn, of_init_fn_2)
         |                 ^~~~~~~~~~~
   include/linux/irqchip.h:37:9: note: in expansion of macro 'OF_DECLARE_2'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |         ^~~~~~~~~~~~
   drivers/irqchip/irq-sifive-plic.c:571:1: note: in expansion of macro 'IRQCHIP_DECLARE'
     571 | IRQCHIP_DECLARE(sifive_plic, "sifive,plic-1.0.0", plic_init);
         | ^~~~~~~~~~~~~~~
>> include/linux/of.h:1478:30: error: initializer element is not constant
    1478 |                      .data = (fn == (fn_type)NULL) ? fn : fn  }
         |                              ^
   include/linux/of.h:1493:17: note: in expansion of macro '_OF_DECLARE'
    1493 |                 _OF_DECLARE(table, name, compat, fn, of_init_fn_2)
         |                 ^~~~~~~~~~~
   include/linux/irqchip.h:37:9: note: in expansion of macro 'OF_DECLARE_2'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |         ^~~~~~~~~~~~
   drivers/irqchip/irq-sifive-plic.c:572:1: note: in expansion of macro 'IRQCHIP_DECLARE'
     572 | IRQCHIP_DECLARE(riscv_plic0, "riscv,plic0", plic_init); /* for legacy systems */
         | ^~~~~~~~~~~~~~~
   include/linux/of.h:1478:30: note: (near initialization for '__of_table_riscv_plic0.data')
    1478 |                      .data = (fn == (fn_type)NULL) ? fn : fn  }
         |                              ^
   include/linux/of.h:1493:17: note: in expansion of macro '_OF_DECLARE'
    1493 |                 _OF_DECLARE(table, name, compat, fn, of_init_fn_2)
         |                 ^~~~~~~~~~~
   include/linux/irqchip.h:37:9: note: in expansion of macro 'OF_DECLARE_2'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |         ^~~~~~~~~~~~
   drivers/irqchip/irq-sifive-plic.c:572:1: note: in expansion of macro 'IRQCHIP_DECLARE'
     572 | IRQCHIP_DECLARE(riscv_plic0, "riscv,plic0", plic_init); /* for legacy systems */
         | ^~~~~~~~~~~~~~~
>> include/linux/of.h:1478:30: error: initializer element is not constant
    1478 |                      .data = (fn == (fn_type)NULL) ? fn : fn  }
         |                              ^
   include/linux/of.h:1493:17: note: in expansion of macro '_OF_DECLARE'
    1493 |                 _OF_DECLARE(table, name, compat, fn, of_init_fn_2)
         |                 ^~~~~~~~~~~
   include/linux/irqchip.h:37:9: note: in expansion of macro 'OF_DECLARE_2'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |         ^~~~~~~~~~~~
   drivers/irqchip/irq-sifive-plic.c:580:1: note: in expansion of macro 'IRQCHIP_DECLARE'
     580 | IRQCHIP_DECLARE(andestech_nceplic100, "andestech,nceplic100", plic_edge_init);
         | ^~~~~~~~~~~~~~~
   include/linux/of.h:1478:30: note: (near initialization for '__of_table_andestech_nceplic100.data')
    1478 |                      .data = (fn == (fn_type)NULL) ? fn : fn  }
         |                              ^
   include/linux/of.h:1493:17: note: in expansion of macro '_OF_DECLARE'
    1493 |                 _OF_DECLARE(table, name, compat, fn, of_init_fn_2)
         |                 ^~~~~~~~~~~
   include/linux/irqchip.h:37:9: note: in expansion of macro 'OF_DECLARE_2'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |         ^~~~~~~~~~~~
   drivers/irqchip/irq-sifive-plic.c:580:1: note: in expansion of macro 'IRQCHIP_DECLARE'
     580 | IRQCHIP_DECLARE(andestech_nceplic100, "andestech,nceplic100", plic_edge_init);
         | ^~~~~~~~~~~~~~~
>> include/linux/of.h:1478:30: error: initializer element is not constant
    1478 |                      .data = (fn == (fn_type)NULL) ? fn : fn  }
         |                              ^
   include/linux/of.h:1493:17: note: in expansion of macro '_OF_DECLARE'
    1493 |                 _OF_DECLARE(table, name, compat, fn, of_init_fn_2)
         |                 ^~~~~~~~~~~
   include/linux/irqchip.h:37:9: note: in expansion of macro 'OF_DECLARE_2'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |         ^~~~~~~~~~~~
   drivers/irqchip/irq-sifive-plic.c:581:1: note: in expansion of macro 'IRQCHIP_DECLARE'
     581 | IRQCHIP_DECLARE(thead_c900_plic, "thead,c900-plic", plic_edge_init);
         | ^~~~~~~~~~~~~~~
   include/linux/of.h:1478:30: note: (near initialization for '__of_table_thead_c900_plic.data')
    1478 |                      .data = (fn == (fn_type)NULL) ? fn : fn  }
         |                              ^
   include/linux/of.h:1493:17: note: in expansion of macro '_OF_DECLARE'
    1493 |                 _OF_DECLARE(table, name, compat, fn, of_init_fn_2)
         |                 ^~~~~~~~~~~
   include/linux/irqchip.h:37:9: note: in expansion of macro 'OF_DECLARE_2'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |         ^~~~~~~~~~~~
   drivers/irqchip/irq-sifive-plic.c:581:1: note: in expansion of macro 'IRQCHIP_DECLARE'
     581 | IRQCHIP_DECLARE(thead_c900_plic, "thead,c900-plic", plic_edge_init);
         | ^~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors
--
   In file included from include/linux/irqchip.h:16,
                    from drivers/irqchip/irq-mst-intc.c:9:
>> include/linux/irqchip.h:24:10: error: implicit declaration of function '__typecheck'; did you mean 'typecheck'? [-Werror=implicit-function-declaration]
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |          ^~~~~~~~~~~
   include/linux/of.h:1478:31: note: in definition of macro '_OF_DECLARE'
    1478 |                      .data = (fn == (fn_type)NULL) ? fn : fn  }
         |                               ^~
   include/linux/irqchip.h:37:9: note: in expansion of macro 'OF_DECLARE_2'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |         ^~~~~~~~~~~~
   include/linux/irqchip.h:37:45: note: in expansion of macro 'typecheck_irq_init_cb'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |                                             ^~~~~~~~~~~~~~~~~~~~~
   drivers/irqchip/irq-mst-intc.c:291:1: note: in expansion of macro 'IRQCHIP_DECLARE'
     291 | IRQCHIP_DECLARE(mst_intc, "mstar,mst-intc", mst_intc_of_init);
         | ^~~~~~~~~~~~~~~
>> include/linux/of.h:1478:30: error: initializer element is not constant
    1478 |                      .data = (fn == (fn_type)NULL) ? fn : fn  }
         |                              ^
   include/linux/of.h:1493:17: note: in expansion of macro '_OF_DECLARE'
    1493 |                 _OF_DECLARE(table, name, compat, fn, of_init_fn_2)
         |                 ^~~~~~~~~~~
   include/linux/irqchip.h:37:9: note: in expansion of macro 'OF_DECLARE_2'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |         ^~~~~~~~~~~~
   drivers/irqchip/irq-mst-intc.c:291:1: note: in expansion of macro 'IRQCHIP_DECLARE'
     291 | IRQCHIP_DECLARE(mst_intc, "mstar,mst-intc", mst_intc_of_init);
         | ^~~~~~~~~~~~~~~
   include/linux/of.h:1478:30: note: (near initialization for '__of_table_mst_intc.data')
    1478 |                      .data = (fn == (fn_type)NULL) ? fn : fn  }
         |                              ^
   include/linux/of.h:1493:17: note: in expansion of macro '_OF_DECLARE'
    1493 |                 _OF_DECLARE(table, name, compat, fn, of_init_fn_2)
         |                 ^~~~~~~~~~~
   include/linux/irqchip.h:37:9: note: in expansion of macro 'OF_DECLARE_2'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |         ^~~~~~~~~~~~
   drivers/irqchip/irq-mst-intc.c:291:1: note: in expansion of macro 'IRQCHIP_DECLARE'
     291 | IRQCHIP_DECLARE(mst_intc, "mstar,mst-intc", mst_intc_of_init);
         | ^~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors
--
   In file included from drivers/irqchip/irq-imx-mu-msi.c:15:
>> include/linux/irqchip.h:24:10: error: implicit declaration of function '__typecheck'; did you mean 'typecheck'? [-Werror=implicit-function-declaration]
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |          ^~~~~~~~~~~
   include/linux/irqchip.h:45:45: note: in expansion of macro 'typecheck_irq_init_cb'
      45 |                                     .data = typecheck_irq_init_cb(fn), },
         |                                             ^~~~~~~~~~~~~~~~~~~~~
   drivers/irqchip/irq-imx-mu-msi.c:445:1: note: in expansion of macro 'IRQCHIP_MATCH'
     445 | IRQCHIP_MATCH("fsl,imx7ulp-mu-msi", imx_mu_imx7ulp_of_init)
         | ^~~~~~~~~~~~~
>> include/linux/irqchip.h:24:9: error: initializer element is not constant
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |         ^
   include/linux/irqchip.h:45:45: note: in expansion of macro 'typecheck_irq_init_cb'
      45 |                                     .data = typecheck_irq_init_cb(fn), },
         |                                             ^~~~~~~~~~~~~~~~~~~~~
   drivers/irqchip/irq-imx-mu-msi.c:445:1: note: in expansion of macro 'IRQCHIP_MATCH'
     445 | IRQCHIP_MATCH("fsl,imx7ulp-mu-msi", imx_mu_imx7ulp_of_init)
         | ^~~~~~~~~~~~~
   include/linux/irqchip.h:24:9: note: (near initialization for 'imx_mu_msi_irqchip_match_table[0].data')
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |         ^
   include/linux/irqchip.h:45:45: note: in expansion of macro 'typecheck_irq_init_cb'
      45 |                                     .data = typecheck_irq_init_cb(fn), },
         |                                             ^~~~~~~~~~~~~~~~~~~~~
   drivers/irqchip/irq-imx-mu-msi.c:445:1: note: in expansion of macro 'IRQCHIP_MATCH'
     445 | IRQCHIP_MATCH("fsl,imx7ulp-mu-msi", imx_mu_imx7ulp_of_init)
         | ^~~~~~~~~~~~~
>> include/linux/irqchip.h:24:9: error: initializer element is not constant
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |         ^
   include/linux/irqchip.h:45:45: note: in expansion of macro 'typecheck_irq_init_cb'
      45 |                                     .data = typecheck_irq_init_cb(fn), },
         |                                             ^~~~~~~~~~~~~~~~~~~~~
   drivers/irqchip/irq-imx-mu-msi.c:446:1: note: in expansion of macro 'IRQCHIP_MATCH'
     446 | IRQCHIP_MATCH("fsl,imx6sx-mu-msi", imx_mu_imx6sx_of_init)
         | ^~~~~~~~~~~~~
   include/linux/irqchip.h:24:9: note: (near initialization for 'imx_mu_msi_irqchip_match_table[1].data')
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |         ^
   include/linux/irqchip.h:45:45: note: in expansion of macro 'typecheck_irq_init_cb'
      45 |                                     .data = typecheck_irq_init_cb(fn), },
         |                                             ^~~~~~~~~~~~~~~~~~~~~
   drivers/irqchip/irq-imx-mu-msi.c:446:1: note: in expansion of macro 'IRQCHIP_MATCH'
     446 | IRQCHIP_MATCH("fsl,imx6sx-mu-msi", imx_mu_imx6sx_of_init)
         | ^~~~~~~~~~~~~
>> include/linux/irqchip.h:24:9: error: initializer element is not constant
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |         ^
   include/linux/irqchip.h:45:45: note: in expansion of macro 'typecheck_irq_init_cb'
      45 |                                     .data = typecheck_irq_init_cb(fn), },
         |                                             ^~~~~~~~~~~~~~~~~~~~~
   drivers/irqchip/irq-imx-mu-msi.c:447:1: note: in expansion of macro 'IRQCHIP_MATCH'
     447 | IRQCHIP_MATCH("fsl,imx8ulp-mu-msi", imx_mu_imx8ulp_of_init)
         | ^~~~~~~~~~~~~
   include/linux/irqchip.h:24:9: note: (near initialization for 'imx_mu_msi_irqchip_match_table[2].data')
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |         ^
   include/linux/irqchip.h:45:45: note: in expansion of macro 'typecheck_irq_init_cb'
      45 |                                     .data = typecheck_irq_init_cb(fn), },
         |                                             ^~~~~~~~~~~~~~~~~~~~~
   drivers/irqchip/irq-imx-mu-msi.c:447:1: note: in expansion of macro 'IRQCHIP_MATCH'
     447 | IRQCHIP_MATCH("fsl,imx8ulp-mu-msi", imx_mu_imx8ulp_of_init)
         | ^~~~~~~~~~~~~
   cc1: some warnings being treated as errors
..


vim +24 include/linux/irqchip.h

f1985002839af80 Marc Zyngier 2021-10-20  22  
f1985002839af80 Marc Zyngier 2021-10-20  23  #define typecheck_irq_init_cb(fn)					\
f1985002839af80 Marc Zyngier 2021-10-20 @24  	(__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
f1985002839af80 Marc Zyngier 2021-10-20  25
  
kernel test robot July 25, 2023, 6:33 p.m. UTC | #2
Hi David,

kernel test robot noticed the following build errors:

[auto build test ERROR on akpm-mm/mm-everything]
[also build test ERROR on linus/master]
[cannot apply to next-20230725]
[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/David-Laight/minmax-Allow-min-max-clamp-if-the-arguments-have-the-same-signedness/20230725-204940
base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link:    https://lore.kernel.org/r/a09512c8526b46759669d0b879144563%40AcuMS.aculab.com
patch subject: [PATCH next resend 2/5] minmax: Allow min()/max()/clamp() if the arguments have the same signedness.
config: mips-randconfig-r016-20230725 (https://download.01.org/0day-ci/archive/20230726/202307260256.nzImScXA-lkp@intel.com/config)
compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project.git 4a5ac14ee968ff0ad5d2cc1ffa0299048db4c88a)
reproduce: (https://download.01.org/0day-ci/archive/20230726/202307260256.nzImScXA-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202307260256.nzImScXA-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/irqchip/irq-mips-cpu.c:288:1: error: call to undeclared function '__typecheck'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     288 | IRQCHIP_DECLARE(cpu_intc, "mti,cpu-interrupt-controller", mips_cpu_irq_of_init);
         | ^
   include/linux/irqchip.h:37:38: note: expanded from macro 'IRQCHIP_DECLARE'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |                                             ^
   include/linux/irqchip.h:24:3: note: expanded from macro 'typecheck_irq_init_cb'
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |          ^
>> drivers/irqchip/irq-mips-cpu.c:288:1: error: initializer element is not a compile-time constant
     288 | IRQCHIP_DECLARE(cpu_intc, "mti,cpu-interrupt-controller", mips_cpu_irq_of_init);
         | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/irqchip.h:37:2: note: expanded from macro 'IRQCHIP_DECLARE'
      37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/of.h:1493:3: note: expanded from macro 'OF_DECLARE_2'
    1493 |                 _OF_DECLARE(table, name, compat, fn, of_init_fn_2)
         |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/of.h:1481:2: note: expanded from macro '_OF_DECLARE'
    1481 |         _OF_DECLARE_STUB(table, name, compat, fn, fn_type)
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/of.h:1470:16: note: expanded from macro '_OF_DECLARE_STUB'
    1470 |                      .data = (fn == (fn_type)NULL) ? fn : fn }
         |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2 errors generated.
--
>> drivers/irqchip/irq-mchp-eic.c:275:1: error: call to undeclared function '__typecheck'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     275 | IRQCHIP_MATCH("microchip,sama7g5-eic", mchp_eic_init)
         | ^
   include/linux/irqchip.h:45:17: note: expanded from macro 'IRQCHIP_MATCH'
      45 |                                     .data = typecheck_irq_init_cb(fn), },
         |                                             ^
   include/linux/irqchip.h:24:3: note: expanded from macro 'typecheck_irq_init_cb'
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |          ^
>> drivers/irqchip/irq-mchp-eic.c:275:1: error: initializer element is not a compile-time constant
     275 | IRQCHIP_MATCH("microchip,sama7g5-eic", mchp_eic_init)
         | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/irqchip.h:45:17: note: expanded from macro 'IRQCHIP_MATCH'
      45 |                                     .data = typecheck_irq_init_cb(fn), },
         |                                             ^~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/irqchip.h:24:2: note: expanded from macro 'typecheck_irq_init_cb'
      24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2 errors generated.


vim +/__typecheck +288 drivers/irqchip/irq-mips-cpu.c

0916b46962cbcac arch/mips/kernel/irq_cpu.c     Gabor Juhos       2013-01-31  281  
afe8dc254711b72 arch/mips/kernel/irq_cpu.c     Andrew Bresticker 2014-09-18  282  int __init mips_cpu_irq_of_init(struct device_node *of_node,
0f84c305351c993 arch/mips/kernel/irq_cpu.c     Andrew Bresticker 2014-09-18  283  				struct device_node *parent)
0f84c305351c993 arch/mips/kernel/irq_cpu.c     Andrew Bresticker 2014-09-18  284  {
0f84c305351c993 arch/mips/kernel/irq_cpu.c     Andrew Bresticker 2014-09-18  285  	__mips_cpu_irq_init(of_node);
0916b46962cbcac arch/mips/kernel/irq_cpu.c     Gabor Juhos       2013-01-31  286  	return 0;
0916b46962cbcac arch/mips/kernel/irq_cpu.c     Gabor Juhos       2013-01-31  287  }
892b8cf06d8a1e7 drivers/irqchip/irq-mips-cpu.c Paul Burton       2015-05-24 @288  IRQCHIP_DECLARE(cpu_intc, "mti,cpu-interrupt-controller", mips_cpu_irq_of_init);
  
David Laight July 26, 2023, 9:19 a.m. UTC | #3
> From: kernel test robot <lkp@intel.com>
> Sent: 25 July 2023 19:33
...
> 
> All errors (new ones prefixed by >>):
> 
> >> drivers/irqchip/irq-mips-cpu.c:288:1: error: call to undeclared function '__typecheck'; ISO C99 and
> later do not support implicit function declarations [-Wimplicit-function-declaration]
>      288 | IRQCHIP_DECLARE(cpu_intc, "mti,cpu-interrupt-controller", mips_cpu_irq_of_init);
>          | ^
>    include/linux/irqchip.h:37:38: note: expanded from macro 'IRQCHIP_DECLARE'
>       37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
>          |                                             ^
>    include/linux/irqchip.h:24:3: note: expanded from macro 'typecheck_irq_init_cb'
>       24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
>          |          ^
> >> drivers/irqchip/irq-mips-cpu.c:288:1: error: initializer element is not a compile-time constant
>      288 | IRQCHIP_DECLARE(cpu_intc, "mti,cpu-interrupt-controller", mips_cpu_irq_of_init);
>          | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/irqchip.h:37:2: note: expanded from macro 'IRQCHIP_DECLARE'
>       37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
>          |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/of.h:1493:3: note: expanded from macro 'OF_DECLARE_2'
>     1493 |                 _OF_DECLARE(table, name, compat, fn, of_init_fn_2)
>          |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/of.h:1481:2: note: expanded from macro '_OF_DECLARE'
>     1481 |         _OF_DECLARE_STUB(table, name, compat, fn, fn_type)
>          |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/of.h:1470:16: note: expanded from macro '_OF_DECLARE_STUB'
>     1470 |                      .data = (fn == (fn_type)NULL) ? fn : fn }
>          |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

It looks like irqchip.h is using __typecheck() which is really
an internal part of the implementation of min() and max().
The patched version doesn't use it - hence the build fail.
I can re-instate it, but this all looks wrong to me.

The type of typecheck_irq_init_cb is the same as that of fn_type (although
they are defined separately).
Both headers seem to be testing the type - and it must match both.
So if the test in of.h worked the one in irqchip.h wouldn't have been added.
So I suspect it doesn't actually do anything - the RHS is NULL, the type
probably doesn't matter.

Possibly:
		.data = {sizeof ((fn) == (fn_type)(fn)) ? fn : fn }
would actually generate the required compile-time error.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
  
David Laight July 26, 2023, 10:25 a.m. UTC | #4
From: Marc Zyngier
> Sent: 26 July 2023 10:51
> 
> On Wed, 26 Jul 2023 10:19:48 +0100,
> David Laight <David.Laight@ACULAB.COM> wrote:
> >
> > > From: kernel test robot <lkp@intel.com>
> > > Sent: 25 July 2023 19:33
> > ...
> > >
> > > All errors (new ones prefixed by >>):
> > >
> > > >> drivers/irqchip/irq-mips-cpu.c:288:1: error: call to undeclared function '__typecheck'; ISO C99
> and
> > > later do not support implicit function declarations [-Wimplicit-function-declaration]
> > >      288 | IRQCHIP_DECLARE(cpu_intc, "mti,cpu-interrupt-controller", mips_cpu_irq_of_init);
> > >          | ^
> > >    include/linux/irqchip.h:37:38: note: expanded from macro 'IRQCHIP_DECLARE'
> > >       37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
> > >          |                                             ^
> > >    include/linux/irqchip.h:24:3: note: expanded from macro 'typecheck_irq_init_cb'
> > >       24 |         (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn)
> > >          |          ^
> > > >> drivers/irqchip/irq-mips-cpu.c:288:1: error: initializer element is not a compile-time constant
> > >      288 | IRQCHIP_DECLARE(cpu_intc, "mti,cpu-interrupt-controller", mips_cpu_irq_of_init);
> > >          | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > >    include/linux/irqchip.h:37:2: note: expanded from macro 'IRQCHIP_DECLARE'
> > >       37 |         OF_DECLARE_2(irqchip, name, compat, typecheck_irq_init_cb(fn))
> > >          |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > >    include/linux/of.h:1493:3: note: expanded from macro 'OF_DECLARE_2'
> > >     1493 |                 _OF_DECLARE(table, name, compat, fn, of_init_fn_2)
> > >          |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > >    include/linux/of.h:1481:2: note: expanded from macro '_OF_DECLARE'
> > >     1481 |         _OF_DECLARE_STUB(table, name, compat, fn, fn_type)
> > >          |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > >    include/linux/of.h:1470:16: note: expanded from macro '_OF_DECLARE_STUB'
> > >     1470 |                      .data = (fn == (fn_type)NULL) ? fn : fn }
> > >          |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >
> > It looks like irqchip.h is using __typecheck() which is really
> > an internal part of the implementation of min() and max().
> > The patched version doesn't use it - hence the build fail.
> > I can re-instate it, but this all looks wrong to me.
> 
> Please see f1985002839a ("irqchip: Provide stronger type checking for
> IRQCHIP_MATCH/IRQCHIP_DECLARE") for the rationale.
> 
> Given that this has uncovered a number of bugs, I'm not letting this
> go without an equivalent replacement.
..
> 
> They are used in different contexts. See IRQCHIP_MATCH().

Ah, I was seeing the error in the expansion of IRQCHIP_DECLARE()
which is doing the type check twice.
It can just pass 'fn'.

The cast NULL check does work.
So IRQCHIP_MATCH() can use the simpler 'fn = (fn_type)NULL ? fn : fn' test
that _OF_DECLARE_STUB() uses.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
  

Patch

diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index 531860e9cc55..10d236ac7da6 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -9,33 +9,31 @@ 
  *
  * - avoid multiple evaluations of the arguments (so side-effects like
  *   "x++" happen only once) when non-constant.
- * - perform strict type-checking (to generate warnings instead of
- *   nasty runtime surprises). See the "unnecessary" pointer comparison
- *   in __typecheck().
+ * - perform signed v unsigned type-checking (to generate compile
+ *   errors instead of nasty runtime surprises).
  * - retain result as a constant expressions when called with only
  *   constant expressions (to avoid tripping VLA warnings in stack
  *   allocation usage).
  */
-#define __typecheck(x, y) \
-	(!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))
+#define __types_ok(x, y) \
+	(is_signed_type(typeof(x)) == is_signed_type(typeof(y)))
 
-#define __no_side_effects(x, y) \
-		(__is_constexpr(x) && __is_constexpr(y))
+#define __cmp_op_min <
+#define __cmp_op_max >
 
-#define __safe_cmp(x, y) \
-		(__typecheck(x, y) && __no_side_effects(x, y))
+#define __cmp(op, x, y)	((x) __cmp_op_##op (y) ? (x) : (y))
 
-#define __cmp(x, y, op)	((x) op (y) ? (x) : (y))
-
-#define __cmp_once(x, y, unique_x, unique_y, op) ({	\
+#define __cmp_once(op, x, y, unique_x, unique_y) ({	\
 		typeof(x) unique_x = (x);		\
 		typeof(y) unique_y = (y);		\
-		__cmp(unique_x, unique_y, op); })
+		static_assert(__types_ok(x, y),		\
+			#op "(" #x ", " #y ") signedness error, fix types or consider " #op "_unsigned() before " #op "_t()"); \
+		__cmp(op, unique_x, unique_y); })
 
-#define __careful_cmp(x, y, op) \
-	__builtin_choose_expr(__safe_cmp(x, y), \
-		__cmp(x, y, op), \
-		__cmp_once(x, y, __UNIQUE_ID(__x), __UNIQUE_ID(__y), op))
+#define __careful_cmp(op, x, y)					\
+	__builtin_choose_expr(__is_constexpr((x) - (y)),	\
+		__cmp(op, x, y),				\
+		__cmp_once(op, x, y, __UNIQUE_ID(__x), __UNIQUE_ID(__y)))
 
 #define __clamp(val, lo, hi)	\
 	((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val)))
@@ -44,17 +42,14 @@ 
 		typeof(val) unique_val = (val);				\
 		typeof(lo) unique_lo = (lo);				\
 		typeof(hi) unique_hi = (hi);				\
+		static_assert(!__is_constexpr((lo) > (hi)) || (lo) <= (hi),		\
+			"clamp() low limit " #lo " greater than high limit " #hi);	\
+		static_assert(__types_ok(val, lo), "clamp() 'lo' signedness error");	\
+		static_assert(__types_ok(val, hi), "clamp() 'hi' signedness error");	\
 		__clamp(unique_val, unique_lo, unique_hi); })
 
-#define __clamp_input_check(lo, hi)					\
-        (BUILD_BUG_ON_ZERO(__builtin_choose_expr(			\
-                __is_constexpr((lo) > (hi)), (lo) > (hi), false)))
-
 #define __careful_clamp(val, lo, hi) ({					\
-	__clamp_input_check(lo, hi) +					\
-	__builtin_choose_expr(__typecheck(val, lo) && __typecheck(val, hi) && \
-			      __typecheck(hi, lo) && __is_constexpr(val) && \
-			      __is_constexpr(lo) && __is_constexpr(hi),	\
+	__builtin_choose_expr(__is_constexpr((val) - (lo) + (hi)),	\
 		__clamp(val, lo, hi),					\
 		__clamp_once(val, lo, hi, __UNIQUE_ID(__val),		\
 			     __UNIQUE_ID(__lo), __UNIQUE_ID(__hi))); })
@@ -64,14 +59,14 @@ 
  * @x: first value
  * @y: second value
  */
-#define min(x, y)	__careful_cmp(x, y, <)
+#define min(x, y)	__careful_cmp(min, x, y)
 
 /**
  * max - return maximum of two values of the same or compatible types
  * @x: first value
  * @y: second value
  */
-#define max(x, y)	__careful_cmp(x, y, >)
+#define max(x, y)	__careful_cmp(max, x, y)
 
 /**
  * min_unsigned - return minimum of two non-negative values
@@ -79,16 +74,16 @@ 
  * @x: first value
  * @y: second value
  */
-#define min_unsigned(x, y)	\
-	__careful_cmp((x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull, <)
+#define min_unsigned(x, y) \
+	__careful_cmp(min, (x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull)
 
 /**
  * max_unsigned - return maximum of two non-negative values
  * @x: first value
  * @y: second value
  */
-#define max_unsigned(x, y)	\
-	__careful_cmp((x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull, >)
+#define max_unsigned(x, y) \
+	__careful_cmp(max, (x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull)
 
 /**
  * min3 - return minimum of three values
@@ -140,7 +135,7 @@ 
  * @x: first value
  * @y: second value
  */
-#define min_t(type, x, y)	__careful_cmp((type)(x), (type)(y), <)
+#define min_t(type, x, y)	__careful_cmp(min, (type)(x), (type)(y))
 
 /**
  * max_t - return maximum of two values, using the specified type
@@ -148,7 +143,7 @@ 
  * @x: first value
  * @y: second value
  */
-#define max_t(type, x, y)	__careful_cmp((type)(x), (type)(y), >)
+#define max_t(type, x, y)	__careful_cmp(max, (type)(x), (type)(y))
 
 /**
  * clamp_t - return a value clamped to a given range using a given type