All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Laight <David.Laight@ACULAB.COM>
To: 'Vincent Mailhol' <mailhol.vincent@wanadoo.fr>,
	Martin Uecker <muecker@gwdg.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	Luc Van Oostenryck <luc.vanoostenryck@gmail.com>,
	Nathan Chancellor <nathan@kernel.org>,
	"Nick Desaulniers" <ndesaulniers@google.com>,
	Bill Wendling <morbo@google.com>,
	Justin Stitt <justinstitt@google.com>,
	Yury Norov <yury.norov@gmail.com>,
	Rasmus Villemoes <linux@rasmusvillemoes.dk>,
	Kees Cook <kees@kernel.org>,
	"Gustavo A. R. Silva" <gustavoars@kernel.org>,
	Jani Nikula <jani.nikula@linux.intel.com>,
	Joonas Lahtinen <joonas.lahtinen@linux.intel.com>,
	Rodrigo Vivi <rodrigo.vivi@intel.com>,
	Tvrtko Ursulin <tursulin@ursulin.net>,
	David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Mike Leach <mike.leach@linaro.org>,
	James Clark <james.clark@linaro.org>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Rikard Falkeborn <rikard.falkeborn@gmail.com>,
	"linux-sparse@vger.kernel.org" <linux-sparse@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"llvm@lists.linux.dev" <llvm@lists.linux.dev>,
	"linux-hardening@vger.kernel.org"
	<linux-hardening@vger.kernel.org>,
	"intel-gfx@lists.freedesktop.org"
	<intel-gfx@lists.freedesktop.org>,
	"dri-devel@lists.freedesktop.org"
	<dri-devel@lists.freedesktop.org>,
	"coresight@lists.linaro.org" <coresight@lists.linaro.org>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>
Subject: RE: [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr()
Date: Fri, 6 Dec 2024 02:25:50 +0000	[thread overview]
Message-ID: <9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com> (raw)
In-Reply-To: <CAMZ6RqLJLP+4d8f5gLfBdFeDVgqy23O+Eo8HRgKCthqBjSHaaw@mail.gmail.com>

From: Vincent Mailhol
> Sent: 05 December 2024 15:31
> 
> -CC: Martin Uecker <Martin.Uecker@med.uni-goettingen.de>
> +CC: Martin Uecker <muecker@gwdg.de>
> (seems that Martin changed his address)
> 
> On Thu. 5 Dec. 2024 at 03:39, David Laight <David.Laight@aculab.com> wrote:
> > > Sent: 02 December 2024 17:33
> > >
> > > From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
> > >
> > > __is_constexpr(), while being one of the most glorious one liner hack
> > > ever witnessed by mankind, is overly complex. Following the adoption
> > > of C11 in the kernel, this macro can be simplified through the use of
> > > a _Generic() selection.
> >
> > You should give credit to some of the earlier patches that do the same.
> > I'm sure there were some related ones from Linus - not applied yet.
> 
> ACK. Would adding a suggested--by Linus tag solve your concern?

I actually suspect the first patches to change __is_constexpr() to
use _Generic were from myself.
I've found a patch I send in November 2023.

> 
> > > First, split the macro in two:
> > >
> > >   - __is_const_zero(x): an helper macro; tells whether x is the
> > >     integer constant expression 0 or something else.
> > >
> > >   - is_const(x): replacement of __is_constexpr(); tells whether x is a
> > >     integer constant expression.
> > >
> > > The split serves two purposes: first make it easier to understand;
> > > second, __is_const_zero() will be reused as a building block for other
> > > is_const_*() macros that will be introduced later on.
> > >
> > > The core principle of __is_constexpr() to abuse the return type of the
> > > ternary operator remains, but all the surrounding sizeof() hack
> > > disappear.
> > >
> > > On a side note, while not relevant to the kernel, __is_constexpr()
> > > relied on the GNU extension that sizeof(void) is 1. const_expr() does
> > > not use any GNU extensions, making it ISO C compliant.
> > >
> > > __is_constexpr() is temporarily kept and will be removed once all its
> > > users get migrated to is_const() (or one of its friend).
> > >
> > > Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
> > > ---
> > >  include/linux/compiler.h | 41 +++++++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 41 insertions(+)
> > >
> > > diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> > > index a2a56a50dd85227a4fdc62236a2710ca37c5ba52..30ce06df4153cfdc0fad9bc7bffab9097f8b0450 100644
> > > --- a/include/linux/compiler.h
> > > +++ b/include/linux/compiler.h
> > > @@ -316,6 +316,47 @@ static inline void *offset_to_ptr(const int *off)
> > >  #define statically_true(x) (__builtin_constant_p(x) && (x))
> > >  #define statically_false(x) (__builtin_constant_p(x) && (x) == 0)
> > >
> > > +/*
> > > + * Whether x is the integer constant expression 0 or something else.
> > > + *
> > > + * Details:
> > > + *   - The C11 standard defines in §6.3.2.3.3
> > > + *       (void *)<integer constant expression with the value 0>
> > > + *     as a null pointer constant (c.f. the NULL macro).
> > > + *   - If x evaluates to the integer constant expression 0,
> > > + *       (void *)(x)
> > > + *     is a null pointer constant. Else, it is a void * expression.
> > > + *   - In a ternary expression:
> > > + *       condition ? operand1 : operand2
> > > + *     if one of the two operands is of type void * and the other one
> > > + *     some other pointer type, the C11 standard defines in §6.5.15.6
> > > + *     the resulting type as below:
> > > + *       if one operand is a null pointer constant, the result has the
> > > + *       type of the other operand; otherwise [...] the result type is
> > > + *       a pointer to an appropriately qualified version of void.
> > > + *   - As such, in
> > > + *       0 ? (void *)(x) : (char *)0
> > > + *     if x is the integer constant expression 0, operand1 is a null
> > > + *     pointer constant and the resulting type is that of operand2:
> > > + *     char *. If x is anything else, the type is void *.
> > > + *   - The (long) cast silences a compiler warning for when x is not 0.
> > > + *   - Finally, the _Generic() dispatches the resulting type into a
> > > + *     Boolean.
> >
> > The comment is absolutely excessive.
> > I'm sure I managed about 2 lines in one of the patches I did.
> 
> I think that Linus made it  clear in:
> 
>   https://lore.kernel.org/all/CAHk-=wgfpLdt7SFFGcByTfHdkvv7AEa3MDu_s_W1kfOxQs49pw@mail.gmail.com/
> 
> that this deserves a detailed comment.

And he wrote one in https://lore.kernel.org/all/CAHk-=wiq=GUNWJwWh1CRAYchW73UmOaSkaCovLatfDKeveZctA@mail.gmail.com/

   /*
    * iff 'x' is a non-zero constant integer expression,
    * then '!(x)' will be a zero constant integer expression,
    * and casting that to 'void *' will result in a NULL pointer.
    * Otherwise casting it to 'void *' will be just a regular 'void *'.
    *
    * The type of '0 ? NULL : (char *)' is 'char *'
    * The type of '0 ? (void *) : (char *) is 'void *'
    */
    #define const_true(x) \
        _Generic(0 ? (void *)((long)!(x)) : (char *)0, char *: 1, void *: 0)



> 
> The details block in the current __is_constexpr() is 37 lines long,
> the details block in __is_const_zero() takes 22 lines. So I would
> argue that I made things better.

The old block was too long :-)

> 
> Unless more people share your concern, I am planning to keep this comment as-is.
> 
> > > + *
> > > + * Glory to Martin Uecker <Martin.Uecker@med.uni-goettingen.de>
> >
> > IIRC Martin has agreed in the past that the accreditation can
> > be removed - especially since it refers to the 'sizeof (void)' trick.
> 
> I tried to look for such message:
> 
>   https://lore.kernel.org/all/?q=f%3A%22martin+uecker%22+__is_constexpr
> 
> but couldn't find it. Do you have the link?
> 
> @Martin, do you agree that I remove the accreditation?
> 
> > > + */
> > > +#define __is_const_zero(x) \
> > > +     _Generic(0 ? (void *)(long)(x) : (char *)0, char *: 1, void *: 0)
> > > +
> > > +/*
> > > + * Returns a constant expression while determining if its argument is a
> > > + * constant expression, most importantly without evaluating the argument.
> >
> > You need to differentiate between a 'constant integer expression'
> > and a 'compile time constant'.
> 
> OK. This one was just copied from the previous __is_constexpr(). I will apply
> "s/constant expression/constant integer expression/g" in v2.
> 
> > > + *
> > > + * If getting a constant expression is not relevant to you, use the more
> > > + * powerful __builtin_constant_p() instead.
> >
> > __builtin_constant_p() is not 'more powerful' it is testing for
> > something different.
> 
> I meant to say that __builtin_constant_p() is more powerful at
> constant folding. But I agree that the comment is not clear.
> 
> What about this?
> 
>   If getting a constant integer expression is not relevant to you, use
>   __builtin_constant_p() which not only returns true if the argument
>   is an integer constant expression, but also if it is a compile time
>   constant.

Complete f***ed tense.

It's not about 'constant folding' and 'powerful' isn't the correct word.
They are checking for two different things.

A 'constant integer expression' is defined by the C language, and is
basically something that is constant when first parsed by the compiler
(my definition) so it can pretty much only contain constants, sizeof()
and offsetof().

__builtin_constant_p() is true if the compiler decides that an expression is
constant. This can track values through inlined function calls and can
change from 'unknown' to 'true' late in the compilation.

	David

> 
> 
> Yours sincerely,
> Vincent Mailhol

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

  reply	other threads:[~2024-12-06  2:26 UTC|newest]

Thread overview: 97+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-02 17:33 [PATCH 00/10] compiler.h: refactor __is_constexpr() into is_const{,_true,_false}() Vincent Mailhol
2024-12-02 17:33 ` Vincent Mailhol via B4 Relay
2024-12-02 17:33 ` [PATCH 01/10] compiler.h: add statically_false() Vincent Mailhol
2024-12-02 17:33   ` Vincent Mailhol via B4 Relay
2024-12-04 18:30   ` David Laight
2024-12-05 15:25     ` Vincent Mailhol
2024-12-06  3:39       ` David Laight
2024-12-06  4:42         ` Vincent Mailhol
2024-12-02 17:33 ` [PATCH 02/10] compiler.h: add is_const() as a replacement of __is_constexpr() Vincent Mailhol
2024-12-02 17:33   ` Vincent Mailhol via B4 Relay
2024-12-04 18:39   ` David Laight
2024-12-04 21:20     ` Yury Norov
2024-12-05 15:31     ` Vincent Mailhol
2024-12-06  2:25       ` David Laight [this message]
2024-12-06  6:14         ` Linus Torvalds
2024-12-06  7:19           ` Vincent Mailhol
2024-12-06  8:49             ` Vincent Mailhol
2024-12-06  8:29           ` Martin Uecker
2024-12-06 18:30           ` Vincent Mailhol
2024-12-06 18:52             ` Linus Torvalds
2024-12-06 19:02               ` Linus Torvalds
2024-12-06 19:06               ` David Laight
2024-12-06 19:15                 ` Linus Torvalds
2024-12-06 19:38                   ` Willy Tarreau
2024-12-06 19:43                     ` David Laight
2024-12-06 19:38                   ` David Laight
2024-12-06 20:23                     ` David Laight
2024-12-07  7:42                       ` Vincent Mailhol
2024-12-07 11:19                         ` David Laight
2024-12-07 12:24                           ` Vincent Mailhol
2024-12-07 18:19                             ` Linus Torvalds
2024-12-07 19:51                               ` Martin Uecker
2024-12-07 20:31                                 ` Linus Torvalds
2024-12-07 20:54                                   ` David Laight
2024-12-07 21:00                                 ` David Laight
2024-12-07 21:06                                   ` Martin Uecker
2024-12-07 21:45                                     ` David Laight
2024-12-09  9:59                               ` Rasmus Villemoes
2024-12-06  6:40         ` Martin Uecker
2024-12-06  7:26           ` Vincent Mailhol
2024-12-07  8:39             ` Martin Uecker
2024-12-07 10:33               ` David Laight
2024-12-07 13:07                 ` Martin Uecker
2024-12-07 18:26                   ` Linus Torvalds
2024-12-07 19:19                     ` Martin Uecker
2024-12-07 20:28                       ` Linus Torvalds
2024-12-07 23:52                         ` Martin Uecker
2024-12-08  1:58                           ` Linus Torvalds
2024-12-08  9:18                             ` Martin Uecker
2024-12-08 11:26                           ` David Laight
2024-12-08 12:38                             ` Martin Uecker
2024-12-08 16:48                               ` David Laight
2024-12-08 18:10                                 ` Martin Uecker
2024-12-08 19:05                                   ` Linus Torvalds
2024-12-07 12:45               ` Vincent Mailhol
2024-12-07 13:18                 ` Martin Uecker
2024-12-07 13:50                   ` Vincent Mailhol
2024-12-07 14:59                     ` Martin Uecker
2024-12-07 15:10                     ` Martin Uecker
2024-12-07 15:23                       ` Vincent Mailhol
2024-12-07 18:07                     ` David Laight
2024-12-06  9:34         ` David Laight
2024-12-02 17:33 ` [PATCH 03/10] compiler.h: add is_const_true() and is_const_false() Vincent Mailhol
2024-12-02 17:33   ` Vincent Mailhol via B4 Relay
2024-12-04 18:48   ` David Laight
2024-12-05 15:48     ` Vincent Mailhol
2024-12-02 17:33 ` [PATCH 04/10] linux/bits.h: simplify GENMASK_INPUT_CHECK() by using is_const_true() Vincent Mailhol
2024-12-02 17:33   ` Vincent Mailhol via B4 Relay
2024-12-04 18:52   ` David Laight
2024-12-05 15:49     ` Vincent Mailhol
2024-12-02 17:33 ` [PATCH 05/10] minmax: simplify __clamp_once() by using is_const_false() Vincent Mailhol
2024-12-02 17:33   ` Vincent Mailhol via B4 Relay
2024-12-04 18:54   ` David Laight
2024-12-05 15:52     ` Vincent Mailhol
2024-12-09 12:32       ` Vincent Mailhol
2024-12-02 17:33 ` [PATCH 06/10] fortify: replace __is_constexpr() by is_const() in strlen() Vincent Mailhol
2024-12-02 17:33   ` Vincent Mailhol via B4 Relay
2024-12-04 18:58   ` David Laight
2024-12-05 15:53     ` Vincent Mailhol
2024-12-02 17:33 ` [PATCH 07/10] overflow: replace __is_constexpr() by is_const() Vincent Mailhol
2024-12-02 17:33   ` Vincent Mailhol via B4 Relay
2024-12-02 17:33 ` [PATCH 08/10] drm/i915/reg: replace __is_const_expr() by is_const_true() or is_const() Vincent Mailhol
2024-12-02 17:33   ` Vincent Mailhol via B4 Relay
2024-12-04 19:00   ` David Laight
2024-12-05 15:56     ` Vincent Mailhol
2024-12-02 17:33 ` [PATCH 09/10] coresight: etm4x: replace __is_const_expr() by is_const() Vincent Mailhol
2024-12-02 17:33   ` Vincent Mailhol via B4 Relay
2024-12-02 17:33 ` [PATCH 10/10] compiler.h: remove __is_constexpr() Vincent Mailhol
2024-12-02 17:33   ` Vincent Mailhol via B4 Relay
2024-12-03 10:19 ` ✗ Fi.CI.CHECKPATCH: warning for compiler.h: refactor __is_constexpr() into is_const{,_true,_false}() Patchwork
2024-12-03 11:32   ` Fi.CI.CHECKPATCH: warning for compiler.h: refactor __is_constexpr() into is_const{, _true, _false}() Vincent Mailhol
2024-12-03 10:19 ` ✗ Fi.CI.SPARSE: warning for compiler.h: refactor __is_constexpr() into is_const{,_true,_false}() Patchwork
2024-12-03 10:50 ` ✓ i915.CI.BAT: success " Patchwork
2024-12-03 12:00 ` ✗ i915.CI.Full: failure " Patchwork
2024-12-04 23:58 ` [PATCH 00/10] " Kees Cook
2024-12-05 15:21   ` [PATCH 00/10] compiler.h: refactor __is_constexpr() into is_const{, _true, _false}() Vincent Mailhol
2024-12-05 15:21     ` [PATCH 00/10] compiler.h: refactor __is_constexpr() into is_const{,_true,_false}() Vincent Mailhol

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9ef03cebb4dd406885d8fdf79aaef043@AcuMS.aculab.com \
    --to=david.laight@aculab.com \
    --cc=airlied@gmail.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=coresight@lists.linaro.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gustavoars@kernel.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=james.clark@linaro.org \
    --cc=jani.nikula@linux.intel.com \
    --cc=joonas.lahtinen@linux.intel.com \
    --cc=justinstitt@google.com \
    --cc=kees@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sparse@vger.kernel.org \
    --cc=linux@rasmusvillemoes.dk \
    --cc=llvm@lists.linux.dev \
    --cc=luc.vanoostenryck@gmail.com \
    --cc=mailhol.vincent@wanadoo.fr \
    --cc=mike.leach@linaro.org \
    --cc=morbo@google.com \
    --cc=muecker@gwdg.de \
    --cc=nathan@kernel.org \
    --cc=ndesaulniers@google.com \
    --cc=rikard.falkeborn@gmail.com \
    --cc=rodrigo.vivi@intel.com \
    --cc=simona@ffwll.ch \
    --cc=suzuki.poulose@arm.com \
    --cc=torvalds@linux-foundation.org \
    --cc=tursulin@ursulin.net \
    --cc=yury.norov@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.