Skip to content

Commit 80f1c8d

Browse files
[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.
1 parent 54a9f0e commit 80f1c8d

File tree

3 files changed

+306
-3
lines changed

3 files changed

+306
-3
lines changed

libcxx/include/stddef.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,28 @@
77
//
88
//===----------------------------------------------------------------------===//
99

10-
#if defined(__need_ptrdiff_t) || defined(__need_size_t) || defined(__need_wchar_t) || defined(__need_NULL) || \
11-
defined(__need_wint_t)
10+
#if defined(__need_ptrdiff_t) || defined(__need_size_t) || defined(__need_rsize_t) || defined(__need_wchar_t) || \
11+
defined(__need_NULL) || defined(__need_nullptr_t) || defined(__need_unreachable) || defined(__need_max_align_t) || \
12+
defined(__need_offsetof) || defined(__need_wint_t)
1213

1314
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1415
# pragma GCC system_header
1516
# endif
1617

18+
# if defined(__need_nullptr_t) && defined(__cplusplus)
19+
// stddef.h will undef __need_nullptr_t
20+
# define __cxx_need_nullptr_t
21+
# endif
22+
1723
# include_next <stddef.h>
1824

19-
#elif !defined(_LIBCPP_STDDEF_H)
25+
# ifdef __cxx_need_nullptr_t
26+
# include <__config>
27+
typedef decltype(nullptr) nullptr_t;
28+
# undef __cxx_need_nullptr_t
29+
# endif
30+
31+
#elif !defined(_LIBCPP_STDDEF_H) || (defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1)
2032
# define _LIBCPP_STDDEF_H
2133

2234
/*
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// This is the same test as clang/test/Headers/stddef.c, but to test the
10+
// libc++ version of stddef.h interacts properly with the clang version.
11+
12+
struct astruct {
13+
char member;
14+
};
15+
16+
ptrdiff_t p0; // expected-error{{unknown type name 'ptrdiff_t'}}
17+
size_t s0; // expected-error{{unknown type name 'size_t'}}
18+
rsize_t r0; // expected-error{{unknown type name 'rsize_t'}}
19+
wchar_t wc0; // wchar_t is a keyword in C++
20+
void* v0 = NULL; // expected-error{{use of undeclared identifier 'NULL'}}
21+
nullptr_t n0; // expected-error{{unknown type name 'nullptr_t'}}
22+
static void f0(void) { unreachable(); } // expected-error{{undeclared identifier 'unreachable'}}
23+
max_align_t m0; // expected-error{{unknown type name 'max_align_t'}}
24+
size_t o0 = offsetof(struct astruct, member); // expected-error{{unknown type name 'size_t'}}
25+
// expected-error@-1{{expected expression}} expected-error@-1{{use of undeclared identifier 'member'}}
26+
wint_t wi0; // expected-error{{unknown type name 'wint_t'}}
27+
28+
#include <stddef.h>
29+
30+
ptrdiff_t p1;
31+
size_t s1;
32+
rsize_t r1;
33+
#if __has_feature(modules)
34+
// expected-error-re@-2{{declaration of 'rsize_t' must be imported from module '{{.+}}' before it is required}}
35+
#else
36+
// expected-error@-4{{unknown type}} expected-note@__stddef_size_t.h:*{{'size_t' declared here}}
37+
#endif
38+
wchar_t wc1;
39+
void* v1 = NULL;
40+
nullptr_t n1;
41+
// unreachable() is declared in <utility> in C++
42+
// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2826.pdf suggests that it maybe should also be
43+
// declared in <stddef.h> too, but it currently isn't.
44+
static void f1(void) { unreachable(); } // expected-error 0+ {{undeclared identifier}}
45+
max_align_t m1;
46+
#if __cplusplus < 201103L
47+
// expected-error@-2{{unknown type}}
48+
#endif
49+
size_t o1 = offsetof(struct astruct, member);
50+
wint_t wi1; // expected-error{{unknown type}}
51+
52+
// rsize_t needs to be opted into via __STDC_WANT_LIB_EXT1__ >= 1.
53+
#define __STDC_WANT_LIB_EXT1__ 1
54+
#include <stddef.h>
55+
ptrdiff_t p2;
56+
size_t s2;
57+
rsize_t r2;
58+
wchar_t wc2;
59+
void* v2 = NULL;
60+
nullptr_t n2;
61+
static void f2(void) { unreachable(); } // expected-error 0+ {{undeclared identifier}}
62+
max_align_t m2;
63+
#if __cplusplus < 201103L
64+
// expected-error@-2{{unknown type}}
65+
#endif
66+
size_t o2 = offsetof(struct astruct, member);
67+
wint_t wi2; // expected-error{{unknown type}}
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// This is the same test as clang/test/Headers/stddefneeds.c, but to test the
10+
// libc++ version of stddef.h interacts properly with the clang version.
11+
12+
struct astruct {
13+
char member;
14+
};
15+
16+
ptrdiff_t p0; // expected-error{{unknown type name 'ptrdiff_t'}}
17+
size_t s0; // expected-error{{unknown type name 'size_t'}}
18+
rsize_t r0; // expected-error{{unknown type name 'rsize_t'}}
19+
wchar_t wc0; // wchar_t is a keyword in C++
20+
void* v0 = NULL; // expected-error{{use of undeclared identifier 'NULL'}}
21+
nullptr_t n0; // expected-error{{unknown type name 'nullptr_t'}}
22+
static void f0(void) { unreachable(); } // expected-error{{undeclared identifier 'unreachable'}}
23+
max_align_t m0; // expected-error{{unknown type name 'max_align_t'}}
24+
size_t o0 = offsetof(struct astruct, member); // expected-error{{unknown type name 'size_t'}}
25+
// expected-error@-1{{expected expression}} expected-error@-1{{use of undeclared identifier 'member'}}
26+
wint_t wi0; // expected-error{{unknown type name 'wint_t'}}
27+
28+
#define __need_ptrdiff_t
29+
#include <stddef.h>
30+
31+
ptrdiff_t p1;
32+
size_t s1;
33+
#if __has_feature(modules)
34+
// expected-error-re@-2{{declaration of 'size_t' must be imported from module '{{.+}}' before it is required}}
35+
#else
36+
// expected-error@-4{{unknown type}}
37+
#endif
38+
rsize_t r1;
39+
#if __has_feature(modules)
40+
// expected-error-re@-2{{declaration of 'rsize_t' must be imported from module '{{.+}}' before it is required}}
41+
#else
42+
// expected-error@-4{{unknown type}}
43+
#endif
44+
wchar_t wc1;
45+
void* v1 = NULL; // expected-error{{undeclared identifier}}
46+
nullptr_t n1; // expected-error{{unknown type}}
47+
static void f1(void) { unreachable(); } // expected-error{{undeclared identifier}}
48+
max_align_t m1;
49+
#if __has_feature(modules)
50+
// expected-error-re@-2{{declaration of 'max_align_t' must be imported from module '{{.+}}' before it is required}}
51+
#else
52+
// expected-error@-4{{unknown type}}
53+
#endif
54+
size_t o1 = offsetof(struct astruct, member);
55+
#if !__has_feature(modules)
56+
// expected-error@-2{{unknown type}}
57+
#endif
58+
// expected-error@-4{{expected expression}} expected-error@-4{{undeclared identifier}}
59+
wint_t wi1; // expected-error{{unknown type}}
60+
61+
// The "declaration must be imported" errors are only emitted the first time a
62+
// known-but-not-visible type is seen. At this point the _Builtin_stddef module
63+
// has been built and all of the types tried, so most of the errors won't be
64+
// repeated below in modules. The types still aren't available, just the errors
65+
// aren't repeated. e.g. rsize_t still isn't available, if r1 above got deleted,
66+
// its error would move to r2 below.
67+
68+
#define __need_size_t
69+
#include <stddef.h>
70+
71+
ptrdiff_t p2;
72+
size_t s2;
73+
rsize_t r2;
74+
#if !__has_feature(modules)
75+
// expected-error@-2{{unknown type}}
76+
#endif
77+
wchar_t wc2;
78+
void* v2 = NULL; // expected-error{{undeclared identifier}}
79+
nullptr_t n2; // expected-error{{unknown type}}
80+
static void f2(void) { unreachable(); } // expected-error{{undeclared identifier}}
81+
max_align_t m2;
82+
#if !__has_feature(modules)
83+
// expected-error@-2{{unknown type}}
84+
#endif
85+
size_t o2 =
86+
offsetof(struct astruct, member); // expected-error{{expected expression}} expected-error{{undeclared identifier}}
87+
wint_t wi2; // expected-error{{unknown type}}
88+
89+
#define __need_rsize_t
90+
#include <stddef.h>
91+
92+
ptrdiff_t p3;
93+
size_t s3;
94+
rsize_t r3;
95+
wchar_t wc3;
96+
void* v3 = NULL; // expected-error{{undeclared identifier}}
97+
nullptr_t n3; // expected-error{{unknown type}}
98+
static void f3(void) { unreachable(); } // expected-error{{undeclared identifier}}
99+
max_align_t m3;
100+
#if !__has_feature(modules)
101+
// expected-error@-2{{unknown type}}
102+
#endif
103+
size_t o3 =
104+
offsetof(struct astruct, member); // expected-error{{expected expression}} expected-error{{undeclared identifier}}
105+
wint_t wi3; // expected-error{{unknown type}}
106+
107+
#define __need_wchar_t
108+
#include <stddef.h>
109+
110+
ptrdiff_t p4;
111+
size_t s4;
112+
rsize_t r4;
113+
wchar_t wc4;
114+
void* v4 = NULL; // expected-error{{undeclared identifier}}
115+
nullptr_t n4; // expected-error{{unknown type}}
116+
static void f4(void) { unreachable(); } // expected-error{{undeclared identifier}}
117+
max_align_t m4;
118+
#if !__has_feature(modules)
119+
// expected-error@-2{{unknown type}}
120+
#endif
121+
size_t o4 =
122+
offsetof(struct astruct, member); // expected-error{{expected expression}} expected-error{{undeclared identifier}}
123+
wint_t wi4; // expected-error{{unknown type}}
124+
125+
#define __need_NULL
126+
#include <stddef.h>
127+
128+
ptrdiff_t p5;
129+
size_t s5;
130+
rsize_t r5;
131+
wchar_t wc5;
132+
void* v5 = NULL;
133+
nullptr_t n5; // expected-error{{unknown type}}
134+
static void f5(void) { unreachable(); } // expected-error{{undeclared identifier}}
135+
max_align_t m5;
136+
#if !__has_feature(modules)
137+
// expected-error@-2{{unknown type}}
138+
#endif
139+
size_t o5 =
140+
offsetof(struct astruct, member); // expected-error{{expected expression}} expected-error{{undeclared identifier}}
141+
wint_t wi5; // expected-error{{unknown type}}
142+
143+
// nullptr_t doesn't get declared before C23 because its definition
144+
// depends on nullptr.
145+
#define __need_nullptr_t
146+
#include <stddef.h>
147+
148+
ptrdiff_t p6;
149+
size_t s6;
150+
rsize_t r6;
151+
wchar_t wc6;
152+
void* v6 = NULL;
153+
nullptr_t n6;
154+
static void f6(void) { unreachable(); } // expected-error{{undeclared identifier}}
155+
max_align_t m6;
156+
#if !__has_feature(modules)
157+
// expected-error@-2{{unknown type}}
158+
#endif
159+
size_t o6 =
160+
offsetof(struct astruct, member); // expected-error{{expected expression}} expected-error{{undeclared identifier}}
161+
wint_t wi6; // expected-error{{unknown type}}
162+
163+
#define __need_unreachable
164+
#include <stddef.h>
165+
166+
ptrdiff_t p7;
167+
size_t s7;
168+
rsize_t r7;
169+
wchar_t wc7;
170+
void* v7 = NULL;
171+
nullptr_t n7;
172+
// __need_unreachable currently declares unreachable(), but the C++23 standard only lists unreachable() in <utility>
173+
// so maybe stddef.h shouldn't declare it even with __need_unreachable.
174+
static void f7(void) { unreachable(); } // expected-error 0+ {{undeclared identifier}}
175+
max_align_t m7;
176+
#if !__has_feature(modules)
177+
// expected-error@-2{{unknown type}}
178+
#endif
179+
size_t o7 =
180+
offsetof(struct astruct, member); // expected-error{{expected expression}} expected-error{{undeclared identifier}}
181+
wint_t wi7; // expected-error{{unknown type}}
182+
183+
#define __need_max_align_t
184+
#include <stddef.h>
185+
186+
ptrdiff_t p8;
187+
size_t s8;
188+
rsize_t r8;
189+
wchar_t wc8;
190+
void* v8 = NULL;
191+
nullptr_t n8;
192+
static void f8(void) { unreachable(); } // expected-error 0+ {{undeclared identifier}}
193+
max_align_t m8;
194+
size_t o8 =
195+
offsetof(struct astruct, member); // expected-error{{expected expression}} expected-error{{undeclared identifier}}
196+
wint_t wi8; // expected-error{{unknown type}}
197+
198+
#define __need_offsetof
199+
#include <stddef.h>
200+
201+
ptrdiff_t p9;
202+
size_t s9;
203+
rsize_t r9;
204+
nullptr_t n9;
205+
static void f9(void) { unreachable(); } // expected-error 0+ {{undeclared identifier}}
206+
wchar_t wc9;
207+
void* v9 = NULL;
208+
max_align_t m9;
209+
size_t o9 = offsetof(struct astruct, member);
210+
wint_t wi9; // expected-error{{unknown type}}
211+
212+
#define __need_wint_t
213+
#include <stddef.h>
214+
215+
ptrdiff_t p10;
216+
size_t s10;
217+
rsize_t r10;
218+
wchar_t wc10;
219+
void* v10 = NULL;
220+
nullptr_t n10;
221+
static void f10(void) { unreachable(); } // expected-error 0+ {{undeclared identifier}}
222+
max_align_t m10;
223+
size_t o10 = offsetof(struct astruct, member);
224+
wint_t wi10;

0 commit comments

Comments
 (0)