From d24b2ade2d8517af8e21e0dc4ee2257521f0d9c1 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Fri, 6 Dec 2024 15:20:55 -0500 Subject: [PATCH 1/2] [libc++] Remove explicit mentions of __need_FOO macros This change has a long history. It was first attempted naively in https://reviews.llvm.org/D131425, which didn't work because we broke the ability for code to include e.g. multiple times and get different definitions based on the pre-defined macros. However, in #86843 we managed to simplify by including the underlying system header outside of any include guards, which worked. This patch applies the same simplification we did to to the other headers that currently mention __need_FOO macros explicitly. --- libcxx/include/module.modulemap | 8 +++--- libcxx/include/stdio.h | 33 ++++++++++++------------ libcxx/include/stdlib.h | 37 +++++++++++++-------------- libcxx/include/wchar.h | 45 ++++++++++++++++----------------- 4 files changed, 60 insertions(+), 63 deletions(-) diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap index 8d862e9f9ba36..5e702813b4926 100644 --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -2282,15 +2282,15 @@ module std_stdbool_h [system] { textual header "stdbool.h" } module std_stddef_h [system] { - // 's __need_* macros require textual inclusion. + // supports being included multiple times with different pre-defined macros textual header "stddef.h" } module std_stdio_h [system] { - // 's __need_* macros require textual inclusion. + // supports being included multiple times with different pre-defined macros textual header "stdio.h" } module std_stdlib_h [system] { - // 's __need_* macros require textual inclusion. + // supports being included multiple times with different pre-defined macros textual header "stdlib.h" } module std_string_h [system] { @@ -2306,7 +2306,7 @@ module std_uchar_h [system] { export * } module std_wchar_h [system] { - // 's __need_* macros require textual inclusion. + // supports being included multiple times with different pre-defined macros textual header "wchar.h" } module std_wctype_h [system] { diff --git a/libcxx/include/stdio.h b/libcxx/include/stdio.h index dcf16dfb63782..7c73671ade08f 100644 --- a/libcxx/include/stdio.h +++ b/libcxx/include/stdio.h @@ -7,17 +7,6 @@ // //===----------------------------------------------------------------------===// -#if defined(__need_FILE) || defined(__need___FILE) - -# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -# endif - -# include_next - -#elif !defined(_LIBCPP_STDIO_H) -# define _LIBCPP_STDIO_H - /* stdio.h synopsis @@ -98,13 +87,23 @@ int ferror(FILE* stream); void perror(const char* s); */ -# if 0 -# else // 0 -# include <__config> +#if 0 +#else // 0 +# include <__config> -# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -# endif +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +# endif + +// The inclusion of the system's is intentionally done once outside of any include +// guards because some code expects to be able to include the underlying system header multiple +// times to get different definitions based on the macros that are set before inclusion. +# if __has_include_next() +# include_next +# endif + +# ifndef _LIBCPP_STDIO_H +# define _LIBCPP_STDIO_H # if __has_include_next() # include_next diff --git a/libcxx/include/stdlib.h b/libcxx/include/stdlib.h index dca4c3a92de14..b8a28809a951c 100644 --- a/libcxx/include/stdlib.h +++ b/libcxx/include/stdlib.h @@ -7,17 +7,6 @@ // //===----------------------------------------------------------------------===// -#if defined(__need_malloc_and_calloc) - -# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -# endif - -# include_next - -#elif !defined(_LIBCPP_STDLIB_H) -# define _LIBCPP_STDLIB_H - /* stdlib.h synopsis @@ -84,13 +73,23 @@ void *aligned_alloc(size_t alignment, size_t size); // C11 */ -# if 0 -# else // 0 -# include <__config> +#if 0 +#else // 0 +# include <__config> -# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -# endif +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +# endif + +// The inclusion of the system's is intentionally done once outside of any include +// guards because some code expects to be able to include the underlying system header multiple +// times to get different definitions based on the macros that are set before inclusion. +# if __has_include_next() +# include_next +# endif + +# if !defined(_LIBCPP_STDLIB_H) +# define _LIBCPP_STDLIB_H # if __has_include_next() # include_next @@ -148,7 +147,7 @@ inline _LIBCPP_HIDE_FROM_ABI lldiv_t div(long long __x, long long __y) _NOEXCEPT # endif # endif // _LIBCPP_MSVCRT } // extern "C++" -# endif // __cplusplus -# endif // 0 +# endif // __cplusplus +# endif // 0 #endif // _LIBCPP_STDLIB_H diff --git a/libcxx/include/wchar.h b/libcxx/include/wchar.h index c91d52c0ca6db..85f16fcf476f2 100644 --- a/libcxx/include/wchar.h +++ b/libcxx/include/wchar.h @@ -7,17 +7,6 @@ // //===----------------------------------------------------------------------===// -#if defined(__need_wint_t) || defined(__need_mbstate_t) - -# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -# endif - -# include_next - -#elif !defined(_LIBCPP_WCHAR_H) -# define _LIBCPP_WCHAR_H - /* wchar.h synopsis @@ -105,25 +94,35 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len, */ -# if 0 -# else // 0 -# include <__config> -# include +#if 0 +#else // 0 +# include <__config> -# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -# endif +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +# endif // We define this here to support older versions of glibc that do // not define this for clang. -# ifdef __cplusplus -# define __CORRECT_ISO_CPP_WCHAR_H_PROTO -# endif +# if defined(__cplusplus) && !defined(__CORRECT_ISO_CPP_WCHAR_H_PROTO) +# define __CORRECT_ISO_CPP_WCHAR_H_PROTO +# endif + +// The inclusion of the system's is intentionally done once outside of any include +// guards because some code expects to be able to include the underlying system header multiple +// times to get different definitions based on the macros that are set before inclusion. +# if __has_include_next() +# include_next +# endif + +# ifndef _LIBCPP_WCHAR_H +# define _LIBCPP_WCHAR_H + +# include <__mbstate_t.h> // provide mbstate_t +# include // provide size_t # if __has_include_next() # include_next -# else -# include <__mbstate_t.h> // make sure we have mbstate_t regardless of the existence of # endif // Determine whether we have const-correct overloads for wcschr and friends. From 057a39d3eb93ddf78fa98def4156cc102d621cab Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Mon, 16 Dec 2024 12:08:04 -0500 Subject: [PATCH 2/2] After investigating CI issues on AIX, I can't explain to myself why this is happening and it looks like a potential compiler bug. XFAILing the AIX test for now until this can be investigated. --- libcxx/test/libcxx/clang_modules_include.gen.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libcxx/test/libcxx/clang_modules_include.gen.py b/libcxx/test/libcxx/clang_modules_include.gen.py index 4a14217738e78..dc815d9c772b5 100644 --- a/libcxx/test/libcxx/clang_modules_include.gen.py +++ b/libcxx/test/libcxx/clang_modules_include.gen.py @@ -49,6 +49,9 @@ // TODO: Investigate why this doesn't work on Picolibc once the locale base API is refactored // UNSUPPORTED: LIBCXX-PICOLIBC-FIXME +// TODO: Fix seemingly circular inclusion or on AIX +// UNSUPPORTED: LIBCXX-AIX-FIXME + {lit_header_restrictions.get(header, '')} {lit_header_undeprecations.get(header, '')} @@ -83,6 +86,9 @@ // TODO: Investigate why this doesn't work on Picolibc once the locale base API is refactored // UNSUPPORTED: LIBCXX-PICOLIBC-FIXME +// TODO: Fix seemingly circular inclusion or on AIX +// UNSUPPORTED: LIBCXX-AIX-FIXME + @import std; """