[libcxx-commits] [libcxx] [libc++] stddef.h needs to #include_next for the new clang __need_ macros (PR #86252)

Ian Anderson via libcxx-commits libcxx-commits at lists.llvm.org
Mon Mar 25 14:32:04 PDT 2024


https://github.com/ian-twilightcoder updated https://github.com/llvm/llvm-project/pull/86252

>From f9a477ce03e497a4fa5ef433435945830d7ef0e9 Mon Sep 17 00:00:00 2001
From: Ian Anderson <iana at apple.com>
Date: Thu, 21 Mar 2024 23:45:55 -0700
Subject: [PATCH] [libc++] stddef.h needs to #include_next for the new clang
 __need_ macros

clang added several __need_ macros to stddef.h that need to be added to the libc++ version as well. clang will also re-enter stddef.h to define rsize_t if __STDC_WANT_LIB_EXT1__ is set, do that in the libc++ one too.
---
 libcxx/include/stddef.h                       |  17 +-
 .../support.c.headers.other/stddef.verify.cpp |  51 ++++++
 .../stddefneeds.verify.cpp                    | 172 ++++++++++++++++++
 3 files changed, 237 insertions(+), 3 deletions(-)
 create mode 100644 libcxx/test/libcxx/language.support/support.c.headers/support.c.headers.other/stddef.verify.cpp
 create mode 100644 libcxx/test/libcxx/language.support/support.c.headers/support.c.headers.other/stddefneeds.verify.cpp

diff --git a/libcxx/include/stddef.h b/libcxx/include/stddef.h
index 887776b150e49d..e26ef622aa11a8 100644
--- a/libcxx/include/stddef.h
+++ b/libcxx/include/stddef.h
@@ -7,16 +7,27 @@
 //
 //===----------------------------------------------------------------------===//
 
-#if defined(__need_ptrdiff_t) || defined(__need_size_t) || defined(__need_wchar_t) || defined(__need_NULL) ||          \
-    defined(__need_wint_t)
+#if defined(__need_ptrdiff_t) || defined(__need_size_t) || defined(__need_rsize_t) || defined(__need_wchar_t) ||       \
+    defined(__need_NULL) || defined(__need_nullptr_t) || defined(__need_unreachable) || defined(__need_max_align_t) || \
+    defined(__need_offsetof) || defined(__need_wint_t)
 
 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #    pragma GCC system_header
 #  endif
 
+#  if defined(__need_nullptr_t) && defined(__cplusplus)
+     // stddef.h will undef __need_nullptr_t
+#    define __cxx_need_nullptr_t
+#  endif
+
 #  include_next <stddef.h>
 
-#elif !defined(_LIBCPP_STDDEF_H)
+#  ifdef __cxx_need_nullptr_t
+typedef decltype(nullptr) nullptr_t;
+#    undef __cxx_need_nullptr_t
+#  endif
+
+#elif !defined(_LIBCPP_STDDEF_H) || (defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1)
 #  define _LIBCPP_STDDEF_H
 
 /*
diff --git a/libcxx/test/libcxx/language.support/support.c.headers/support.c.headers.other/stddef.verify.cpp b/libcxx/test/libcxx/language.support/support.c.headers/support.c.headers.other/stddef.verify.cpp
new file mode 100644
index 00000000000000..26d53871a8a35b
--- /dev/null
+++ b/libcxx/test/libcxx/language.support/support.c.headers/support.c.headers.other/stddef.verify.cpp
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This is the same test as clang/test/Headers/stddef.c, but to test the
+// libc++ version of stddef.h interacts properly with the clang version.
+
+struct astruct { char member; };
+
+ptrdiff_t p0; // expected-error{{unknown type name 'ptrdiff_t'}}
+size_t s0; // expected-error{{unknown type name 'size_t'}}
+rsize_t r0; // expected-error{{unknown type name 'rsize_t'}}
+wchar_t wc0; // wchar_t is a keyword in C++
+void *v0 = NULL; // expected-error{{use of undeclared identifier 'NULL'}}
+nullptr_t n0; // expected-error{{unknown type name 'nullptr_t'}}
+static void f0(void) { unreachable(); } // expected-error{{undeclared identifier 'unreachable'}}
+max_align_t m0; // expected-error{{unknown type name 'max_align_t'}}
+size_t o0 = offsetof(struct astruct, member); // expected-error{{unknown type name 'size_t'}} expected-error{{expected expression}} expected-error{{use of undeclared identifier 'member'}}
+wint_t wi0; // expected-error{{unknown type name 'wint_t'}}
+
+#include <stddef.h>
+
+ptrdiff_t p1;
+size_t s1;
+rsize_t r1; // expected-error{{unknown type}} expected-note at __stddef_size_t.h:*{{'size_t' declared here}}
+wchar_t wc1;
+void *v1 = NULL;
+nullptr_t n1;
+// unreachable() is declared in <utility> in C++
+static void f1(void) { unreachable(); } // expected-error{{undeclared identifier}}
+max_align_t m1;
+size_t o1 = offsetof(struct astruct, member);
+wint_t wi1; // expected-error{{unknown type}}
+
+// rsize_t needs to be opted into via __STDC_WANT_LIB_EXT1__ >= 1.
+#define __STDC_WANT_LIB_EXT1__ 1
+#include <stddef.h>
+ptrdiff_t p2;
+size_t s2;
+rsize_t r2;
+wchar_t wc2;
+void *v2 = NULL;
+nullptr_t n2;
+static void f2(void) { unreachable(); } // expected-error{{undeclared identifier}}
+max_align_t m2;
+size_t o2 = offsetof(struct astruct, member);
+wint_t wi2; // expected-error{{unknown type}}
diff --git a/libcxx/test/libcxx/language.support/support.c.headers/support.c.headers.other/stddefneeds.verify.cpp b/libcxx/test/libcxx/language.support/support.c.headers/support.c.headers.other/stddefneeds.verify.cpp
new file mode 100644
index 00000000000000..b8a7aae737d714
--- /dev/null
+++ b/libcxx/test/libcxx/language.support/support.c.headers/support.c.headers.other/stddefneeds.verify.cpp
@@ -0,0 +1,172 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This is the same test as clang/test/Headers/stddefneeds.c, but to test the
+// libc++ version of stddef.h interacts properly with the clang version.
+
+struct astruct { char member; };
+
+ptrdiff_t p0; // expected-error{{unknown type name 'ptrdiff_t'}}
+size_t s0; // expected-error{{unknown type name 'size_t'}}
+rsize_t r0; // expected-error{{unknown type name 'rsize_t'}}
+wchar_t wc0; // wchar_t is a keyword in C++
+void *v0 = NULL; // expected-error{{use of undeclared identifier 'NULL'}}
+nullptr_t n0; // expected-error{{unknown type name 'nullptr_t'}}
+static void f0(void) { unreachable(); } // expected-error{{undeclared identifier 'unreachable'}}
+max_align_t m0; // expected-error{{unknown type name 'max_align_t'}}
+size_t o0 = offsetof(struct astruct, member); // expected-error{{unknown type name 'size_t'}} expected-error{{expected expression}} expected-error{{use of undeclared identifier 'member'}}
+wint_t wi0; // expected-error{{unknown type name 'wint_t'}}
+
+#define __need_ptrdiff_t
+#include <stddef.h>
+
+ptrdiff_t p1;
+size_t s1; // expected-error{{unknown type}}
+rsize_t r1; // expected-error{{unknown type}}
+wchar_t wc1;
+void *v1 = NULL; // expected-error{{undeclared identifier}}
+nullptr_t n1; // expected-error{{unknown type}}
+static void f1(void) { unreachable(); } // expected-error{{undeclared identifier}}
+max_align_t m1; // expected-error{{unknown type}}
+size_t o1 = offsetof(struct astruct, member); // expected-error{{unknown type}} expected-error{{expected expression}} expected-error{{undeclared identifier}}
+wint_t wi1; // expected-error{{unknown type}}
+
+// The "must be declared before used" errors are only emitted the first time a
+// known-but-not-visible type is seen. At this point the _Builtin_stddef module
+// has been built and all of the types tried, so most of the errors won't be
+// repeated below in modules. The types still aren't available, just the errors
+// aren't repeated. e.g. rsize_t still isn't available, if r1 above got deleted,
+// its error would move to r2 below.
+
+#define __need_size_t
+#include <stddef.h>
+
+ptrdiff_t p2;
+size_t s2;
+rsize_t r2; // expected-error{{unknown type}}
+wchar_t wc2;
+void *v2 = NULL; // expected-error{{undeclared identifier}}
+nullptr_t n2; // expected-error{{unknown type}}
+static void f2(void) { unreachable(); } // expected-error{{undeclared identifier}}
+max_align_t m2; // expected-error{{unknown type}}
+size_t o2 = offsetof(struct astruct, member); // expected-error{{expected expression}} expected-error{{undeclared identifier}}
+wint_t wi2; // expected-error{{unknown type}}
+
+#define __need_rsize_t
+#include <stddef.h>
+
+ptrdiff_t p3;
+size_t s3;
+rsize_t r3;
+wchar_t wc3;
+void *v3 = NULL; // expected-error{{undeclared identifier}}
+nullptr_t n3; // expected-error{{unknown type}}
+static void f3(void) { unreachable(); } // expected-error{{undeclared identifier}}
+max_align_t m3; // expected-error{{unknown type}}
+size_t o3 = offsetof(struct astruct, member); // expected-error{{expected expression}} expected-error{{undeclared identifier}}
+wint_t wi3; // expected-error{{unknown type}}
+
+#define __need_wchar_t
+#include <stddef.h>
+
+ptrdiff_t p4;
+size_t s4;
+rsize_t r4;
+wchar_t wc4;
+void *v4 = NULL; // expected-error{{undeclared identifier}}
+nullptr_t n4; // expected-error{{unknown type}}
+static void f4(void) { unreachable(); } // expected-error{{undeclared identifier}}
+max_align_t m4; // expected-error{{unknown type}}
+size_t o4 = offsetof(struct astruct, member); // expected-error{{expected expression}} expected-error{{undeclared identifier}}
+wint_t wi4; // expected-error{{unknown type}}
+
+#define __need_NULL
+#include <stddef.h>
+
+ptrdiff_t p5;
+size_t s5;
+rsize_t r5;
+wchar_t wc5;
+void *v5 = NULL;
+nullptr_t n5; // expected-error{{unknown type}}
+static void f5(void) { unreachable(); } // expected-error{{undeclared identifier}}
+max_align_t m5; // expected-error{{unknown type}}
+size_t o5 = offsetof(struct astruct, member); // expected-error{{expected expression}} expected-error{{undeclared identifier}}
+wint_t wi5; // expected-error{{unknown type}}
+
+// nullptr_t doesn't get declared before C23 because its definition
+// depends on nullptr.
+#define __need_nullptr_t
+#include <stddef.h>
+
+ptrdiff_t p6;
+size_t s6;
+rsize_t r6;
+wchar_t wc6;
+void *v6 = NULL;
+nullptr_t n6;
+static void f6(void) { unreachable(); } // expected-error{{undeclared identifier}}
+max_align_t m6; // expected-error{{unknown type}}
+size_t o6 = offsetof(struct astruct, member); // expected-error{{expected expression}} expected-error{{undeclared identifier}}
+wint_t wi6; // expected-error{{unknown type}}
+
+#define __need_unreachable
+#include <stddef.h>
+
+ptrdiff_t p7;
+size_t s7;
+rsize_t r7;
+wchar_t wc7;
+void *v7 = NULL;
+nullptr_t n7;
+static void f7(void) { unreachable(); }
+max_align_t m7; // expected-error{{unknown type}}
+size_t o7 = offsetof(struct astruct, member); // expected-error{{expected expression}} expected-error{{undeclared identifier}}
+wint_t wi7; // expected-error{{unknown type}}
+
+#define __need_max_align_t
+#include <stddef.h>
+
+ptrdiff_t p8;
+size_t s8;
+rsize_t r8;
+wchar_t wc8;
+void *v8 = NULL;
+nullptr_t n8;
+static void f8(void) { unreachable(); }
+max_align_t m8;
+size_t o8 = offsetof(struct astruct, member); // expected-error{{expected expression}} expected-error{{undeclared identifier}}
+wint_t wi8; // expected-error{{unknown type}}
+
+#define __need_offsetof
+#include <stddef.h>
+
+ptrdiff_t p9;
+size_t s9;
+rsize_t r9;
+nullptr_t n9;
+static void f9(void) { unreachable(); }
+wchar_t wc9;
+void *v9 = NULL;
+max_align_t m9;
+size_t o9 = offsetof(struct astruct, member);
+wint_t wi9; // expected-error{{unknown type}}
+
+#define __need_wint_t
+#include <stddef.h>
+
+ptrdiff_t p10;
+size_t s10;
+rsize_t r10;
+wchar_t wc10;
+void *v10 = NULL;
+nullptr_t n10;
+static void f10(void) { unreachable(); }
+max_align_t m10;
+size_t o10 = offsetof(struct astruct, member);
+wint_t wi10;



More information about the libcxx-commits mailing list