[libcxx-commits] [libcxx] [libc++] Remove explicit mentions of __need_FOO macros (PR #119025)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Mon Dec 16 09:09:15 PST 2024


https://github.com/ldionne updated https://github.com/llvm/llvm-project/pull/119025

>From d24b2ade2d8517af8e21e0dc4ee2257521f0d9c1 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
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. <stdio.h> multiple times and get
different definitions based on the pre-defined macros.

However, in #86843 we managed to simplify <stddef.h> by including
the underlying system header outside of any include guards, which
worked.

This patch applies the same simplification we did to <stddef.h> 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 8d862e9f9ba361..5e702813b49264 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] {
-  // <stddef.h>'s __need_* macros require textual inclusion.
+  // <stddef.h> supports being included multiple times with different pre-defined macros
   textual header "stddef.h"
 }
 module std_stdio_h [system] {
-  // <stdio.h>'s __need_* macros require textual inclusion.
+  // <stdio.h> supports being included multiple times with different pre-defined macros
   textual header "stdio.h"
 }
 module std_stdlib_h [system] {
-  // <stdlib.h>'s __need_* macros require textual inclusion.
+  // <stdlib.h> 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] {
-  // <wchar.h>'s __need_* macros require textual inclusion.
+  // <wchar.h> 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 dcf16dfb637827..7c73671ade08f0 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 <stdio.h>
-
-#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 <stdio.h> 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(<stdio.h>)
+#    include_next <stdio.h>
+#  endif
+
+#  ifndef _LIBCPP_STDIO_H
+#    define _LIBCPP_STDIO_H
 
 #    if __has_include_next(<stdio.h>)
 #      include_next <stdio.h>
diff --git a/libcxx/include/stdlib.h b/libcxx/include/stdlib.h
index dca4c3a92de14a..b8a28809a951c4 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 <stdlib.h>
-
-#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 <stdlib.h> 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(<stdlib.h>)
+#    include_next <stdlib.h>
+#  endif
+
+#  if !defined(_LIBCPP_STDLIB_H)
+#    define _LIBCPP_STDLIB_H
 
 #    if __has_include_next(<stdlib.h>)
 #      include_next <stdlib.h>
@@ -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 c91d52c0ca6db1..85f16fcf476f22 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 <wchar.h>
-
-#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 <stddef.h>
+#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 <wchar.h> 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 <wchar.h> 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(<wchar.h>)
+#    include_next <wchar.h>
+#  endif
+
+#  ifndef _LIBCPP_WCHAR_H
+#    define _LIBCPP_WCHAR_H
+
+#    include <__mbstate_t.h> // provide mbstate_t
+#    include <stddef.h>      // provide size_t
 
 #    if __has_include_next(<wchar.h>)
 #      include_next <wchar.h>
-#    else
-#      include <__mbstate_t.h> // make sure we have mbstate_t regardless of the existence of <wchar.h>
 #    endif
 
 // Determine whether we have const-correct overloads for wcschr and friends.

>From 057a39d3eb93ddf78fa98def4156cc102d621cab Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
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 4a14217738e78d..dc815d9c772b5b 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 <wchar.h> 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 <wchar.h> on AIX
+// UNSUPPORTED: LIBCXX-AIX-FIXME
+
 @import std;
 
 """



More information about the libcxx-commits mailing list