From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.5 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_LOW,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 7077 invoked from network); 31 May 2023 14:00:58 -0000 Received: from second.openwall.net (193.110.157.125) by inbox.vuxu.org with ESMTPUTF8; 31 May 2023 14:00:58 -0000 Received: (qmail 30274 invoked by uid 550); 31 May 2023 14:00:54 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 30238 invoked from network); 31 May 2023 14:00:54 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=inria.fr; s=dc; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=F97rBWUmJ58ZDb8sPQLITtl+4RSMLdW+ITAxOtI9NA8=; b=lUtcAB5HRg8S5yP3n1MJZpVfs0EyMGvfIOVAjoYM18k6iVPJpJj9ij7M D0WavFjgfCMVFkkBSmElF4Jt76HhHi//mstavuXRQcGlClPYRFSMXAOzy vSKXVDgSq6xTD8XjaiJb/2JEWRENhdFDKfF2bS1upjL4eAy62RzefJtcS g=; Authentication-Results: mail2-relais-roc.national.inria.fr; dkim=none (message not signed) header.i=none; spf=SoftFail smtp.mailfrom=Jens.Gustedt@inria.fr; dmarc=fail (p=none dis=none) d=inria.fr X-IronPort-AV: E=Sophos;i="6.00,207,1681164000"; d="scan'208";a="110510129" From: Jens Gustedt To: musl@lists.openwall.com Date: Wed, 31 May 2023 16:00:25 +0200 Message-Id: <0f4c603261279d9afcdf1791691971f072d77b33.1685541439.git.Jens.Gustedt@inria.fr> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [musl] [C23 const 1/2] C23: change bsearch to a macro that respects the const contract This adds a macro interface to stdlib that has an additional cast of the return value to `void const*` for the case that the argument to the call was also const-qualified. Nothing changes for the function itself, only the identifier has to be protected with (), such that the macro does not expand for the function declaration or definition. The implementation of this macro might be a bit unusual for musl. It serves the purpose of better error tracking if users call the macro with the wrong argument. (0) Programming _Generic is hard. It needs that all choices are syntactically and semantically valid. Otherwise the users drowns in warnings and errors. (1) Compilers nowadays track on which line in a macro definition an error appears. For _Generic it helps a lot if the compiler presents the exact choice which leads to a diagnostic. (2) All object pointer values with unqualified or const-qualified target are valid. Therefore we use a trick that maps all const-qualified targets to void const*. (3) The case of a wrongly qualified pointer argument would lead to a misleading diagnostic without the cast. --- include/stdlib.h | 12 +++++++++++- src/include/stdlib.h | 2 ++ src/stdlib/bsearch.c | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/include/stdlib.h b/include/stdlib.h index 72522cd6..b7abf8c4 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -60,7 +60,17 @@ char *getenv (const char *); int system (const char *); -void *bsearch (const void *, const void *, size_t, size_t, int (*)(const void *, const void *)); +void * (bsearch) (const void *, const void *, size_t, size_t, int (*)(const void *, const void *)); +#if __STDC_VERSION__ > 201112L +# define bsearch(K, B, N, S, C) \ + _Generic( \ + /* ensure conversion to a void pointer */ \ + 1 ? (B) : (void*)1, \ + void const*: (void const*)bsearch((K), (void const*)(B), (N), (S), (C)), \ + /* volatile qualification of *B is an error for this call */ \ + default: bsearch((K), (B), (N), (S), (C)) \ +) +#endif void qsort (void *, size_t, size_t, int (*)(const void *, const void *)); int abs (int); diff --git a/src/include/stdlib.h b/src/include/stdlib.h index 812b04de..f0b03df9 100644 --- a/src/include/stdlib.h +++ b/src/include/stdlib.h @@ -16,4 +16,6 @@ hidden void *__libc_calloc(size_t, size_t); hidden void *__libc_realloc(void *, size_t); hidden void __libc_free(void *); +#undef bsearch + #endif diff --git a/src/stdlib/bsearch.c b/src/stdlib/bsearch.c index fe050ea3..4f62ea37 100644 --- a/src/stdlib/bsearch.c +++ b/src/stdlib/bsearch.c @@ -1,6 +1,6 @@ #include -void *bsearch(const void *key, const void *base, size_t nel, size_t width, int (*cmp)(const void *, const void *)) +void *(bsearch)(const void *key, const void *base, size_t nel, size_t width, int (*cmp)(const void *, const void *)) { void *try; int sign; -- 2.34.1