lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <f8d71557-b767-422d-976f-ab9902da87b8@wanadoo.fr>
Date: Tue, 31 Dec 2024 13:58:04 +0900
From: Vincent Mailhol <mailhol.vincent@...adoo.fr>
To: Yury Norov <yury.norov@...il.com>
Cc: Linus Torvalds <torvalds@...ux-foundation.org>,
 Rasmus Villemoes <linux@...musvillemoes.dk>,
 Luc Van Oostenryck <luc.vanoostenryck@...il.com>,
 linux-kernel@...r.kernel.org, linux-sparse@...r.kernel.org,
 Rikard Falkeborn <rikard.falkeborn@...il.com>
Subject: Re: [PATCH v4 1/2] compiler.h: add const_true()

On 31/12/2024 at 03:32, Yury Norov wrote:
> On Wed, Nov 13, 2024 at 10:53:55AM -0800, Yury Norov wrote:
>> On Thu, Nov 14, 2024 at 02:18:32AM +0900, Vincent Mailhol wrote:
>>> __builtin_constant_p() is known for not always being able to produce
>>> constant expression [1] which led to the introduction of
>>> __is_constexpr() [2]. Because of its dependency on
>>> __builtin_constant_p(), statically_true() suffers from the same
>>> issues.
>>>
>>> For example:
>>>
>>>   void foo(int a)
>>>   {
>>>   	 /* fail on GCC */
>>>   	BUILD_BUG_ON_ZERO(statically_true(a));
>>>
>>>   	 /* fail on both clang and GCC */
>>>   	static char arr[statically_true(a) ? 1 : 2];
>>>   }
>>>
>>> For the same reasons why __is_constexpr() was created to cover
>>> __builtin_constant_p() edge cases, __is_constexpr() can be used to
>>> resolve statically_true() limitations.
>>>
>>> Note that, somehow, GCC is not always able to fold this:
>>>
>>>   __is_constexpr(x) && (x)
>>>
>>> It is OK in BUILD_BUG_ON_ZERO() but not in array declarations nor in
>>> static_assert():
>>>
>>>   void bar(int a)
>>>   {
>>>   	/* success */
>>>   	BUILD_BUG_ON_ZERO(__is_constexpr(a) && (a));
>>>
>>>   	/* fail on GCC */
>>>   	static char arr[__is_constexpr(a) && (a) ? 1 : 2];
>>>
>>>   	/* fail on GCC */
>>>   	static_assert(__is_constexpr(a) && (a));
>>>   }
>>>
>>> Encapsulating the expression in a __builtin_choose_expr() switch
>>> resolves all these failed tests.
>>>
>>> Define a new const_true() macro which, by making use of the
>>> __builtin_choose_expr() and __is_constexpr(x) combo, always produces a
>>> constant expression.
>>>
>>> It should be noted that statically_true() is the only one able to fold
>>> tautologic expressions in which at least one on the operands is not a
>>> constant expression. For example:
>>>
>>>   statically_true(true || var)
>>>   statically_true(var == var)
>>>   statically_true(var * 0 + 1)
>>>   statically_true(!(var * 8 % 4))
>>>
>>> always evaluates to true, whereas all of these would be false under
>>> const_true() if var is not a constant expression [3].
>>>
>>> For this reason, usage of const_true() be should the exception.
>>> Reflect in the documentation that const_true() is less powerful and
>>> that statically_true() is the overall preferred solution.
>>>
>>> [1] __builtin_constant_p cannot resolve to const when optimizing
>>> Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19449
>>>
>>> [2] commit 3c8ba0d61d04 ("kernel.h: Retain constant expression output for max()/min()")
>>> Link: https://git.kernel.org/torvalds/c/3c8ba0d61d04
>>>
>>> [3] https://godbolt.org/z/c61PMxqbK
>>>
>>> Signed-off-by: Vincent Mailhol <mailhol.vincent@...adoo.fr>
>>
>> For the series:
>>
>> Reviewed-by: Yury Norov <yury.norov@...il.com>
>>
>> If no objections, I'll move it with my tree.
> 
> This is already in my branch, but there was a discussion after I pulled
> it. Can you guys tell me what is your conclusion on that? Should I
> keep it in the branch, or drop?

I see... Thanks for asking!

After receiving criticism on this series, I was assuming that I had to
rework it. But if given the option, I definitely prefer if you keep it
in your tree.

The new series [1] I sent depends on this patch from David:

  https://git.kernel.org/akpm/mm/c/c108f4c2947a

which is causing build failure in linux-next. Because of that, I put my
new series of hiatus. And the merge windows approaches, so I would
rather like that we just keep this series of two patches for 6.13 and
that I continue the bigger refactor of is_const() in the 6.14 cycle (by
then, the dependencies on David patch will hopefully be fixed).

Note that the new series does not conflict with this one. So if this
series gets merged first, I see only benefit: it will offload some work
and make the new series a bit smaller.

[1]
https://lore.kernel.org/all/20241203-is_constexpr-refactor-v1-0-4e4cbaecc216@wanadoo.fr/


Yours sincerely,
Vincent Mailhol


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ