This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH 1/4] qsort_chk: call from gcc_qsort instead of wrapping it
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: Alexander Monakov <amonakov at ispras dot ru>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 28 Aug 2018 11:22:00 +0200
- Subject: Re: [PATCH 1/4] qsort_chk: call from gcc_qsort instead of wrapping it
- References: <alpine.LNX.2.20.13.1808281157510.10521@monopod.intra.ispras.ru>
On Tue, Aug 28, 2018 at 11:03 AM Alexander Monakov <amonakov@ispras.ru> wrote:
>
> Hi,
>
> This is an independently useful patch that makes it easier to introduce
> gcc_stablesort.
>
> Swap responsibilities of gcc_qsort and qsort_chk: call the checking function
> from the sorting function instead of wrapping gcc_qsort with qsort_chk.
OK.
> * gcc/sort.cc (gcc_qsort) [CHECKING_P]: Call qsort_chk.
> * gcc/system.h (qsort): Always redirect to gcc_qsort. Update comment.
> * gcc/vec.c (qsort_chk): Do not call gcc_qsort. Update comment.
>
> diff --git a/gcc/sort.cc b/gcc/sort.cc
> index 293e2058f89..9f8ee12e13b 100644
> --- a/gcc/sort.cc
> +++ b/gcc/sort.cc
> @@ -229,4 +229,7 @@ gcc_qsort (void *vbase, size_t n, size_t size, cmp_fn *cmp)
> mergesort (base, &c, n, base, (char *)buf);
> if (buf != scratch)
> free (buf);
> +#if CHECKING_P
> + qsort_chk (vbase, n, size, cmp);
> +#endif
> }
> diff --git a/gcc/system.h b/gcc/system.h
> index f87fbaae69e..203c6a4f0cf 100644
> --- a/gcc/system.h
> +++ b/gcc/system.h
> @@ -1197,17 +1197,13 @@ helper_const_non_const_cast (const char *p)
> /* Get definitions of HOST_WIDE_INT. */
> #include "hwint.h"
>
> -/* qsort comparator consistency checking: except in release-checking compilers,
> - redirect 4-argument qsort calls to qsort_chk; keep 1-argument invocations
> +/* GCC qsort API-compatible functions: except in release-checking compilers,
> + redirect 4-argument qsort calls to gcc_qsort; keep 1-argument invocations
> corresponding to vec::qsort (cmp): they use C qsort internally anyway. */
> void qsort_chk (void *, size_t, size_t, int (*)(const void *, const void *));
> void gcc_qsort (void *, size_t, size_t, int (*)(const void *, const void *));
> #define PP_5th(a1, a2, a3, a4, a5, ...) a5
> #undef qsort
> -#if CHECKING_P
> -#define qsort(...) PP_5th (__VA_ARGS__, qsort_chk, 3, 2, qsort, 0) (__VA_ARGS__)
> -#else
> #define qsort(...) PP_5th (__VA_ARGS__, gcc_qsort, 3, 2, qsort, 0) (__VA_ARGS__)
> -#endif
>
> #endif /* ! GCC_SYSTEM_H */
> diff --git a/gcc/vec.c b/gcc/vec.c
> index beb857fd838..ac3226b5fcb 100644
> --- a/gcc/vec.c
> +++ b/gcc/vec.c
> @@ -201,21 +201,12 @@ qsort_chk_error (const void *p1, const void *p2, const void *p3,
> internal_error ("qsort checking failed");
> }
>
> -/* Wrapper around qsort with checking that CMP is consistent on given input.
> -
> - Strictly speaking, passing invalid (non-transitive, non-anti-commutative)
> - comparators to libc qsort can result in undefined behavior. Therefore we
> - should ideally perform consistency checks prior to invoking qsort, but in
> - order to do that optimally we'd need to sort the array ourselves beforehand
> - with a sorting routine known to be "safe". Instead, we expect that most
> - implementations in practice will still produce some permutation of input
> - array even for invalid comparators, which enables us to perform checks on
> - the output array. */
> +/* Verify anti-symmetry and transitivity for comparator CMP on sorted array
> + of N SIZE-sized elements pointed to by BASE. */
> void
> qsort_chk (void *base, size_t n, size_t size,
> int (*cmp)(const void *, const void *))
> {
> - gcc_qsort (base, n, size, cmp);
> #if 0
> #define LIM(n) (n)
> #else
> --
> 2.13.3
>