mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
libc: Implement qualifier-preserving standard library functions
Several standard library functions are specified to return an unqualified pointer while accepting a pointer to a potentially const-qualified object. N3020 addresses this behaviour, discarding qualifiers due to incompatible pointer types, by introducing qualifier-preserving macros for the affected set of standard library functions. Add `__qualsel()` helper to `<sys/cdefs.h>`, implemented using the generic selection, and define qualifier-preserving macros for that set of functions in `<string.h>`, `<wchar.h>`, and `<stdlib.h>`. Macros are gated on `_STDC_VERSION__ >= 202311L && !__cplusplus`, therefore there is no behavioural change for earlier C modes or C++ translation units. The kernel is likewise unaffected, as it does not include userland headers. As function-like macros, they are transparent except at a call site where the address-of operator is applied, the macro is suppressed via `#undef`, or the identifier appears in parenthesised form; all of which cause the underlying function designator to be used instead. Reviewed by: fuz Approved by: fuz (mentor) MFC after: 1 month Pull Request: https://github.com/freebsd/freebsd-src/pull/2288
This commit is contained in:
13 files changed
+187
-33
No files matched your search
@@ -418,4 +418,16 @@ errno_t qsort_s(void *, rsize_t, rsize_t,
|
||||
__END_DECLS
|
||||
__NULLABILITY_PRAGMA_POP
|
||||
|
||||
#if defined(__qualsel) && !defined(__cplusplus) && \
|
||||
defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
|
||||
#define bsearch(key, base, nmemb, size, compar) __qualsel((base), \
|
||||
(const void *)(bsearch)((key), (base), (nmemb), (size), (compar)), \
|
||||
(bsearch)((key), (base), (nmemb), (size), (compar)))
|
||||
#ifdef __BLOCKS__
|
||||
#define bsearch_b(key, base, nmemb, size, compar) __qualsel((base), \
|
||||
(const void *)(bsearch_b)((key), (base), (nmemb), (size), (compar)), \
|
||||
(bsearch_b)((key), (base), (nmemb), (size), (compar)))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* !_STDLIB_H_ */
|
||||
@@ -205,4 +205,32 @@ errno_t memset_s(void *, rsize_t, int, rsize_t);
|
||||
#endif /* __EXT1_VISIBLE */
|
||||
__END_DECLS
|
||||
|
||||
#if defined(__qualsel) && !defined(__cplusplus) && \
|
||||
defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
|
||||
#define memchr(b, c, n) __qualsel((b), \
|
||||
(const void *)(memchr)((b), (c), (n)), (memchr)((b), (c), (n)))
|
||||
#define strchr(s, c) __qualsel((s), \
|
||||
(const char *)(strchr)((s), (c)), (strchr)((s), (c)))
|
||||
#define strpbrk(s, charset) __qualsel((s), \
|
||||
(const char *)(strpbrk)((s), (charset)), (strpbrk)((s), (charset)))
|
||||
#define strrchr(s, c) __qualsel((s), \
|
||||
(const char *)(strrchr)((s), (c)), (strrchr)((s), (c)))
|
||||
#define strstr(s, find) __qualsel((s), \
|
||||
(const char *)(strstr)((s), (find)), (strstr)((s), (find)))
|
||||
#if __BSD_VISIBLE
|
||||
#define memmem(b, blen, pat, plen) __qualsel((b), \
|
||||
(const void *)(memmem)((b), (blen), (pat), (plen)), \
|
||||
(memmem)((b), (blen), (pat), (plen)))
|
||||
#define memrchr(b, c, n) __qualsel((b), \
|
||||
(const void *)(memrchr)((b), (c), (n)), (memrchr)((b), (c), (n)))
|
||||
#define strcasestr(s, find) __qualsel((s), \
|
||||
(const char *)(strcasestr)((s), (find)), (strcasestr)((s), (find)))
|
||||
#define strchrnul(s, c) __qualsel((s), \
|
||||
(const char *)(strchrnul)((s), (c)), (strchrnul)((s), (c)))
|
||||
#define strnstr(s, find, slen) __qualsel((s), \
|
||||
(const char *)(strnstr)((s), (find), (slen)), \
|
||||
(strnstr)((s), (find), (slen)))
|
||||
#endif /* __BSD_VISIBLE */
|
||||
#endif
|
||||
|
||||
#endif /* _STRING_H_ */
|
||||
@@ -246,4 +246,18 @@ size_t wcslcpy(wchar_t *, const wchar_t *, size_t);
|
||||
#endif
|
||||
__END_DECLS
|
||||
|
||||
#if defined(__qualsel) && !defined(__cplusplus) && \
|
||||
defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
|
||||
#define wcschr(s, c) __qualsel((s), \
|
||||
(const wchar_t *)(wcschr)((s), (c)), (wcschr)((s), (c)))
|
||||
#define wcspbrk(s, set) __qualsel((s), \
|
||||
(const wchar_t *)(wcspbrk)((s), (set)), (wcspbrk)((s), (set)))
|
||||
#define wcsrchr(s, c) __qualsel((s), \
|
||||
(const wchar_t *)(wcsrchr)((s), (c)), (wcsrchr)((s), (c)))
|
||||
#define wcsstr(s, find) __qualsel((s), \
|
||||
(const wchar_t *)(wcsstr)((s), (find)), (wcsstr)((s), (find)))
|
||||
#define wmemchr(s, c, n) __qualsel((s), \
|
||||
(const wchar_t *)(wmemchr)((s), (c), (n)), (wmemchr)((s), (c), (n)))
|
||||
#endif
|
||||
|
||||
#endif /* !_WCHAR_H_ */
|
||||
Reference in new issue
Block a user