Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 19 Jan 2023 23:36:05 +0000
From:      Jessica Clarke <jrtc27@freebsd.org>
To:        John Baldwin <jhb@FreeBSD.org>
Cc:        "src-committers@freebsd.org" <src-committers@FreeBSD.org>, "dev-commits-src-all@freebsd.org" <dev-commits-src-all@FreeBSD.org>, "dev-commits-src-main@freebsd.org" <dev-commits-src-main@FreeBSD.org>
Subject:   Re: git: 43703bc489ec - main - stdlib.h: Fix qsort_r compatibility with GCC 12.
Message-ID:  <0F50986C-BC29-4A7A-89F0-DAB3863BF51B@freebsd.org>
In-Reply-To: <8C902ED3-D9F8-4F88-8D43-F8E4809C9D44@freebsd.org>
References:  <202301192249.30JMnCXf040410@gitrepo.freebsd.org> <F42A1D72-387E-4F3F-8C27-C95C5A244E1D@freebsd.org> <8C902ED3-D9F8-4F88-8D43-F8E4809C9D44@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On 19 Jan 2023, at 23:31, Jessica Clarke <jrtc27@FreeBSD.org> wrote:
>=20
> On 19 Jan 2023, at 23:11, Jessica Clarke <jrtc27@FreeBSD.org> wrote:
>>=20
>> On 19 Jan 2023, at 22:49, John Baldwin <jhb@FreeBSD.org> wrote:
>>>=20
>>> The branch main has been updated by jhb:
>>>=20
>>> URL: =
https://cgit.FreeBSD.org/src/commit/?id=3D43703bc489ec504b947b869045c492ed=
38c1a69c
>>>=20
>>> commit 43703bc489ec504b947b869045c492ed38c1a69c
>>> Author:     John Baldwin <jhb@FreeBSD.org>
>>> AuthorDate: 2023-01-19 22:48:52 +0000
>>> Commit:     John Baldwin <jhb@FreeBSD.org>
>>> CommitDate: 2023-01-19 22:48:52 +0000
>>>=20
>>>  stdlib.h: Fix qsort_r compatibility with GCC 12.
>>>=20
>>>  GCC 12 (unlike GCC 9) does not match a function argument passed to =
the
>>>  old qsort_r() API (as is used in the qsort_r_compat test) to a
>>>  function pointer type via __generic.  It treats the function type =
as a
>>>  distinct type from a function pointer.  As a workaround, add a =
second
>>>  definition of qsort_r for GCC 12 which uses the bare function type.
>>=20
>> As far as I can tell both versions of GCC behave the same. The
>> difference is whether __generic is using _Generic or
>> __builtin_choose_expr with __builtin_types_compatible_p, since =
function
>> and function pointer types are not compatible. Clang will take the
>> __has_extension path, but GCC will take the builtins path, and so =
Clang
>> works but GCC doesn=E2=80=99t.
>>=20
>> As a result of this change you=E2=80=99ve likely broken code that =
does
>> qsort_r(..., &f) as that will have the opposite problem. The right =
fix
>> is to force arg5 to decay, such as by (ab)using the comma operator =
with
>> __generic((0, arg5), ...). I guess that probably belongs in the
>> fallback implementation of __generic though, not here, which would =
give
>> the following real fix:
>>=20
>> diff --git a/sys/sys/cdefs.h b/sys/sys/cdefs.h
>> index 83ba7584e5b9..f7eff4768151 100644
>> --- a/sys/sys/cdefs.h
>> +++ b/sys/sys/cdefs.h
>> @@ -312,6 +312,9 @@
>> * __generic().  Unlike _Generic(), this macro can only distinguish
>> * between a single type, so it requires nested invocations to
>> * distinguish multiple cases.
>> + *
>> + * Note that the comma operator is used to force expr to decay in =
order to
>> + * match _Generic.
>> */
>>=20
>> #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >=3D 201112L) || \
>> @@ -321,7 +324,7 @@
>> #elif __GNUC_PREREQ__(3, 1) && !defined(__cplusplus)
>> #define	__generic(expr, t, yes, no)					=
\
>> 	__builtin_choose_expr(						=
\
>> -	    __builtin_types_compatible_p(__typeof(expr), t), yes, no)
>> +	    __builtin_types_compatible_p(__typeof((0, expr)), t), yes, =
no)
>=20
> With (expr) instead of expr, of course...

And as for why GCC 9 works:

It doesn=E2=80=99t. The tests just aren=E2=80=99t built because =
MK_CXX=3Dno disables
MK_TESTS. GCC 12 only hits it because it=E2=80=99s new enough to be able =
to
build libc++ and not force MK_CXX=3Dno.

It would be nice to unpick that...

Jess

> Jess
>=20
>> #endif
>>=20
>> /*
>>=20
>> Does that work instead for you after reverting this commit?
>>=20
>> Jess
>>=20
>>>  Reviewed by:    emaste
>>>  Differential Revision:  https://reviews.freebsd.org/D37410
>>> ---
>>> include/stdlib.h | 6 ++++++
>>> 1 file changed, 6 insertions(+)
>>>=20
>>> diff --git a/include/stdlib.h b/include/stdlib.h
>>> index 754e8f5f5fd4..30d24aea1c10 100644
>>> --- a/include/stdlib.h
>>> +++ b/include/stdlib.h
>>> @@ -352,9 +352,15 @@ void __qsort_r_compat(void *, size_t, size_t, =
void *,
>>> __sym_compat(qsort_r, __qsort_r_compat, FBSD_1.0);
>>> #endif
>>> #if defined(__generic) && !defined(__cplusplus)
>>> +#if __GNUC__ =3D=3D 12
>>> +#define	qsort_r(base, nel, width, arg4, arg5)				=
\
>>> +    __generic(arg5, int (void *, const void *, const void *),		=
\
>>> +	__qsort_r_compat, qsort_r)(base, nel, width, arg4, arg5)
>>> +#else
>>> #define	qsort_r(base, nel, width, arg4, arg5)				=
\
>>>   __generic(arg5, int (*)(void *, const void *, const void *),	=
\
>>>       __qsort_r_compat, qsort_r)(base, nel, width, arg4, arg5)
>>> +#endif
>>> #elif defined(__cplusplus)
>>> __END_DECLS
>>> extern "C++" {




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?0F50986C-BC29-4A7A-89F0-DAB3863BF51B>