Skip to content

Commit 7568fda

Browse files
Merge pull request swiftlang#7615 from ian-twilightcoder/stddef_needs
[cherry-pick stable/20230725] [Headers] Replace __need_STDDEF_H_misc with specific __need_ macros
2 parents 723fee6 + c7a94c1 commit 7568fda

File tree

3 files changed

+272
-30
lines changed

3 files changed

+272
-30
lines changed

clang/lib/Headers/stddef.h

Lines changed: 57 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,48 @@
88
*/
99

1010
#if !defined(__STDDEF_H) || defined(__need_ptrdiff_t) || \
11-
defined(__need_size_t) || defined(__need_wchar_t) || \
12-
defined(__need_NULL) || defined(__need_wint_t)
11+
defined(__need_size_t) || defined(__need_rsize_t) || \
12+
defined(__need_wchar_t) || defined(__need_NULL) || \
13+
defined(__need_nullptr_t) || defined(__need_unreachable) || \
14+
defined(__need_max_align_t) || defined(__need_offsetof) || \
15+
defined(__need_wint_t) || \
16+
(defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1)
1317

1418
#if !defined(__need_ptrdiff_t) && !defined(__need_size_t) && \
15-
!defined(__need_wchar_t) && !defined(__need_NULL) && \
16-
!defined(__need_wint_t)
19+
!defined(__need_rsize_t) && !defined(__need_wchar_t) && \
20+
!defined(__need_NULL) && !defined(__need_nullptr_t) && \
21+
!defined(__need_unreachable) && !defined(__need_max_align_t) && \
22+
!defined(__need_offsetof) && !defined(__need_wint_t)
1723
/* Always define miscellaneous pieces when modules are available. */
1824
#if !__has_feature(modules)
1925
#define __STDDEF_H
2026
#endif
2127
#define __need_ptrdiff_t
2228
#define __need_size_t
29+
/* ISO9899:2011 7.20 (C11 Annex K): Define rsize_t if __STDC_WANT_LIB_EXT1__ is
30+
* enabled. */
31+
#if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1
32+
#define __need_rsize_t
33+
#endif
2334
#define __need_wchar_t
2435
#define __need_NULL
25-
#define __need_STDDEF_H_misc
26-
/* __need_wint_t is intentionally not defined here. */
36+
/* FIXME: This is using the placeholder dates Clang produces for these macros
37+
in C2x mode; switch to the correct values once they've been published. */
38+
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L) || \
39+
defined(__cplusplus)
40+
#define __need_nullptr_t
41+
#endif
42+
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
43+
#define __need_unreachable
44+
#endif
45+
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
46+
(defined(__cplusplus) && __cplusplus >= 201103L)
47+
#define __need_max_align_t
48+
#endif
49+
#define __need_offsetof
50+
/* wint_t is provided by <wchar.h> and not <stddef.h>. It's here
51+
* for compatibility, but must be explicitly requested. Therefore
52+
* __need_wint_t is intentionally not defined here. */
2753
#endif
2854

2955
#if defined(__need_ptrdiff_t)
@@ -48,18 +74,16 @@ typedef __SIZE_TYPE__ size_t;
4874
#undef __need_size_t
4975
#endif /*defined(__need_size_t) */
5076

51-
#if defined(__need_STDDEF_H_misc)
52-
/* ISO9899:2011 7.20 (C11 Annex K): Define rsize_t if __STDC_WANT_LIB_EXT1__ is
53-
* enabled. */
54-
#if (defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1 && \
55-
!defined(_RSIZE_T)) || __has_feature(modules)
77+
#if defined(__need_rsize_t)
78+
#if !defined(_RSIZE_T) || __has_feature(modules)
5679
/* Always define rsize_t when modules are available. */
5780
#if !__has_feature(modules)
5881
#define _RSIZE_T
5982
#endif
6083
typedef __SIZE_TYPE__ rsize_t;
6184
#endif
62-
#endif /* defined(__need_STDDEF_H_misc) */
85+
#undef __need_rsize_t
86+
#endif /* defined(__need_rsize_t) */
6387

6488
#if defined(__need_wchar_t)
6589
#if !defined(__cplusplus) || (defined(_MSC_VER) && !_NATIVE_WCHAR_T_DEFINED)
@@ -88,34 +112,37 @@ typedef __WCHAR_TYPE__ wchar_t;
88112
#else
89113
# define NULL ((void*)0)
90114
#endif
115+
#undef __need_NULL
116+
#endif /* defined(__need_NULL) */
117+
118+
#if defined(__need_nullptr_t)
91119
#ifdef __cplusplus
92120
#if defined(_MSC_EXTENSIONS) && defined(_NATIVE_NULLPTR_SUPPORTED)
93-
namespace std { typedef decltype(nullptr) nullptr_t; }
121+
namespace std {
122+
typedef decltype(nullptr) nullptr_t;
123+
}
94124
using ::std::nullptr_t;
95125
#endif
96-
#endif
97-
#undef __need_NULL
98-
#endif /* defined(__need_NULL) */
99-
100-
/* FIXME: This is using the placeholder dates Clang produces for these macros
101-
in C2x mode; switch to the correct values once they've been published. */
102-
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
126+
#else
103127
typedef typeof(nullptr) nullptr_t;
104-
#endif /* defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L */
128+
#endif
129+
#undef __need_nullptr_t
130+
#endif /* defined(__need_nullptr_t) */
105131

106-
#if defined(__need_STDDEF_H_misc) && defined(__STDC_VERSION__) && \
107-
__STDC_VERSION__ >= 202000L
132+
#if defined(__need_unreachable)
108133
#define unreachable() __builtin_unreachable()
109-
#endif /* defined(__need_STDDEF_H_misc) && >= C23 */
134+
#undef __need_unreachable
135+
#endif /* defined(__need_unreachable) */
110136

111-
#if defined(__need_STDDEF_H_misc)
112-
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
113-
(defined(__cplusplus) && __cplusplus >= 201103L)
137+
#if defined(__need_max_align_t)
114138
#include "__stddef_max_align_t.h"
115-
#endif
139+
#undef __need_max_align_t
140+
#endif /* defined(__need_max_align_t) */
141+
142+
#if defined(__need_offsetof)
116143
#define offsetof(t, d) __builtin_offsetof(t, d)
117-
#undef __need_STDDEF_H_misc
118-
#endif /* defined(__need_STDDEF_H_misc) */
144+
#undef __need_offsetof
145+
#endif /* defined(__need_offsetof) */
119146

120147
/* Some C libraries expect to see a wint_t here. Others (notably MinGW) will use
121148
__WINT_TYPE__ directly; accommodate both by requiring __need_wint_t */

clang/test/Headers/stddef.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify=c99 -std=c99 %s
2+
// RUN: %clang_cc1 -fsyntax-only -verify=c11 -std=c11 %s
3+
// RUN: %clang_cc1 -fsyntax-only -verify=c23 -std=c23 %s
4+
5+
struct astruct { char member; };
6+
7+
ptrdiff_t p0; // c99-error{{unknown type name 'ptrdiff_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
8+
size_t s0; // c99-error{{unknown type name 'size_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
9+
rsize_t r0; // c99-error{{unknown type name 'rsize_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
10+
wchar_t wc0; // c99-error{{unknown type name 'wchar_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
11+
void *v0 = NULL; // c99-error{{use of undeclared identifier 'NULL'}} c11-error{{undeclared identifier}} c23-error{{undeclared identifier}}
12+
nullptr_t n0; // c99-error{{unknown type name 'nullptr_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
13+
static void f0(void) { unreachable(); } // c99-error{{call to undeclared function 'unreachable'}} c11-error{{undeclared function}} c23-error{{undeclared identifier}}
14+
max_align_t m0; // c99-error{{unknown type name 'max_align_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
15+
size_t o0 = offsetof(struct astruct, member); // c99-error{{unknown type name 'size_t'}} c99-error{{call to undeclared function 'offsetof'}} c99-error{{expected expression}} c99-error{{use of undeclared identifier 'member'}} \
16+
c11-error{{unknown type}} c11-error{{undeclared function}} c11-error{{expected expression}} c11-error{{undeclared identifier}} \
17+
c23-error{{unknown type}} c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
18+
wint_t wi0; // c99-error{{unknown type name 'wint_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
19+
20+
#include <stddef.h>
21+
22+
ptrdiff_t p1;
23+
size_t s1;
24+
rsize_t r1; // c99-error{{unknown type}} c11-error{{unknown type}} c23-error{{unknown type}}
25+
// [email protected]:*{{'size_t' declared here}} [email protected]:*{{'size_t' declared here}} [email protected]:*{{'size_t' declared here}}
26+
wchar_t wc1;
27+
void *v1 = NULL;
28+
nullptr_t n1; // c99-error{{unknown type}} c11-error{{unknown type}}
29+
static void f1(void) { unreachable(); } // c99-error{{undeclared function}} c11-error{{undeclared function}}
30+
max_align_t m1; // c99-error{{unknown type}}
31+
size_t o1 = offsetof(struct astruct, member);
32+
wint_t wi1; // c99-error{{unknown type}} c11-error{{unknown type}} c23-error{{unknown type}}
33+
34+
// rsize_t needs to be opted into via __STDC_WANT_LIB_EXT1__ >= 1.
35+
#define __STDC_WANT_LIB_EXT1__ 1
36+
#include <stddef.h>
37+
ptrdiff_t p2;
38+
size_t s2;
39+
rsize_t r2;
40+
wchar_t wc2;
41+
void *v2 = NULL;
42+
nullptr_t n2; // c99-error{{unknown type}} c11-error{{unknown type}}
43+
static void f2(void) { unreachable(); } // c99-error{{undeclared function}} c11-error{{undeclared function}}
44+
max_align_t m2; // c99-error{{unknown type}}
45+
size_t o2 = offsetof(struct astruct, member);
46+
wint_t wi2; // c99-error{{unknown type}} c11-error{{unknown type}} c23-error{{unknown type}}

clang/test/Headers/stddefneeds.c

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify=c99 -std=c99 %s
2+
// RUN: %clang_cc1 -fsyntax-only -verify=c23 -std=c23 %s
3+
4+
// Use C99 to verify that __need_ can be used to get types that wouldn't normally be available.
5+
6+
struct astruct { char member; };
7+
8+
ptrdiff_t p0; // c99-error{{unknown type name 'ptrdiff_t'}} c23-error{{unknown type}}
9+
size_t s0; // c99-error{{unknown type name 'size_t'}} c23-error{{unknown type}}
10+
rsize_t r0; // c99-error{{unknown type name 'rsize_t'}} c23-error{{unknown type}}
11+
wchar_t wc0; // c99-error{{unknown type name 'wchar_t'}} c23-error{{unknown type}}
12+
void *v0 = NULL; // c99-error{{use of undeclared identifier 'NULL'}} c23-error{{undeclared identifier}}
13+
nullptr_t n0; // c99-error{{unknown type name 'nullptr_t'}} c23-error{{unknown type}}
14+
static void f0(void) { unreachable(); } // c99-error{{call to undeclared function 'unreachable'}} c23-error{{undeclared identifier 'unreachable'}}
15+
max_align_t m0; // c99-error{{unknown type name 'max_align_t'}} c23-error{{unknown type}}
16+
size_t o0 = offsetof(struct astruct, member); // c99-error{{unknown type name 'size_t'}} c99-error{{call to undeclared function 'offsetof'}} c99-error{{expected expression}} c99-error{{use of undeclared identifier 'member'}} \
17+
c23-error{{unknown type name 'size_t'}} c23-error{{undeclared identifier 'offsetof'}} c23-error{{expected expression}} c23-error{{use of undeclared identifier 'member'}}
18+
wint_t wi0; // c99-error{{unknown type name 'wint_t'}} c23-error{{unknown type}}
19+
20+
#define __need_ptrdiff_t
21+
#include <stddef.h>
22+
23+
ptrdiff_t p1;
24+
size_t s1; // c99-error{{unknown type}} c23-error{{unknown type}}
25+
rsize_t r1; // c99-error{{unknown type}} c23-error{{unknown type}}
26+
wchar_t wc1; // c99-error{{unknown type}} c23-error{{unknown type}}
27+
void *v1 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}}
28+
nullptr_t n1; // c99-error{{unknown type}} c23-error{{unknown type}}
29+
static void f1(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}}
30+
max_align_t m1; // c99-error{{unknown type}} c23-error{{unknown type}}
31+
size_t o1 = offsetof(struct astruct, member); // c99-error{{unknown type}} c99-error{{expected expression}} c99-error{{undeclared identifier}} \
32+
c23-error{{unknown type}} c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
33+
wint_t wi1; // c99-error{{unknown type}} c23-error{{unknown type}}
34+
35+
#define __need_size_t
36+
#include <stddef.h>
37+
38+
ptrdiff_t p2;
39+
size_t s2;
40+
rsize_t r2; // c99-error{{unknown type}} c23-error{{unknown type}}
41+
// [email protected]:*{{'size_t' declared here}} [email protected]:*{{'size_t' declared here}}
42+
wchar_t wc2; // c99-error{{unknown type}} c23-error{{unknown type}}
43+
void *v2 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}}
44+
nullptr_t n2; // c99-error{{unknown type}} c23-error{{unknown type}}
45+
static void f2(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}}
46+
max_align_t m2; // c99-error{{unknown type}} c23-error{{unknown type}}
47+
size_t o2 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
48+
c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
49+
wint_t wi2; // c99-error{{unknown type}} c23-error{{unknown type}}
50+
51+
#define __need_rsize_t
52+
#include <stddef.h>
53+
54+
ptrdiff_t p3;
55+
size_t s3;
56+
rsize_t r3;
57+
wchar_t wc3; // c99-error{{unknown type}} c23-error{{unknown type}}
58+
void *v3 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}}
59+
nullptr_t n3; // c99-error{{unknown type}} c23-error{{unknown type}}
60+
static void f3(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}}
61+
max_align_t m3; // c99-error{{unknown type}} c23-error{{unknown type}}
62+
size_t o3 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
63+
c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
64+
wint_t wi3; // c99-error{{unknown type}} c23-error{{unknown type}}
65+
66+
#define __need_wchar_t
67+
#include <stddef.h>
68+
69+
ptrdiff_t p4;
70+
size_t s4;
71+
rsize_t r4;
72+
wchar_t wc4;
73+
void *v4 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}}
74+
nullptr_t n4; // c99-error{{unknown type}} c23-error{{unknown type}}
75+
static void f4(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}}
76+
max_align_t m4; // c99-error{{unknown type}} c23-error{{unknown type}}
77+
size_t o4 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
78+
c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
79+
wint_t wi4; // c99-error{{unknown type}} c23-error{{unknown type}}
80+
81+
#define __need_NULL
82+
#include <stddef.h>
83+
84+
ptrdiff_t p5;
85+
size_t s5;
86+
rsize_t r5;
87+
wchar_t wc5;
88+
void *v5 = NULL;
89+
nullptr_t n5; // c99-error{{unknown type}} c23-error{{unknown type}}
90+
static void f5(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}}
91+
max_align_t m5; // c99-error{{unknown type}} c23-error{{unknown type}}
92+
size_t o5 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
93+
c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
94+
wint_t wi5; // c99-error{{unknown type}} c23-error{{unknown type}}
95+
96+
// __need_nullptr_t generates an error in <C23 because its definition
97+
// depends on nullptr.
98+
#define __need_nullptr_t
99+
#include <stddef.h> // [email protected]:*{{expected function body}}
100+
101+
ptrdiff_t p6;
102+
size_t s6;
103+
rsize_t r6;
104+
wchar_t wc6;
105+
void *v6 = NULL;
106+
nullptr_t n6; // c99-error{{unknown type}}
107+
static void f6(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}}
108+
max_align_t m6; // c99-error{{unknown type}} c23-error{{unknown type}}
109+
size_t o6 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
110+
c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
111+
wint_t wi6; // c99-error{{unknown type}} c23-error{{unknown type}}
112+
113+
#define __need_unreachable
114+
#include <stddef.h>
115+
116+
ptrdiff_t p7;
117+
size_t s7;
118+
rsize_t r7;
119+
wchar_t wc7;
120+
void *v7 = NULL;
121+
nullptr_t n7 ; // c99-error{{unknown type}}
122+
static void f7(void) { unreachable(); }
123+
max_align_t m7; // c99-error{{unknown type}} c23-error{{unknown type}}
124+
size_t o7 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
125+
c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
126+
wint_t wi7; // c99-error{{unknown type}} c23-error{{unknown type}}
127+
128+
#define __need_max_align_t
129+
#include <stddef.h>
130+
131+
ptrdiff_t p8;
132+
size_t s8;
133+
rsize_t r8;
134+
wchar_t wc8;
135+
void *v8 = NULL;
136+
nullptr_t n8; // c99-error{{unknown type}}
137+
static void f8(void) { unreachable(); }
138+
max_align_t m8;
139+
size_t o8 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
140+
c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
141+
wint_t wi8; // c99-error{{unknown type}} c23-error{{unknown type}}
142+
143+
#define __need_offsetof
144+
#include <stddef.h>
145+
146+
ptrdiff_t p9;
147+
size_t s9;
148+
rsize_t r9;
149+
nullptr_t n9; // c99-error{{unknown type}}
150+
static void f9(void) { unreachable(); }
151+
wchar_t wc9;
152+
void *v9 = NULL;
153+
max_align_t m9;
154+
size_t o9 = offsetof(struct astruct, member);
155+
wint_t wi9; // c99-error{{unknown type}} c23-error{{unknown type}}
156+
157+
#define __need_wint_t
158+
#include <stddef.h>
159+
160+
ptrdiff_t p10;
161+
size_t s10;
162+
rsize_t r10;
163+
wchar_t wc10;
164+
void *v10 = NULL;
165+
nullptr_t n10; // c99-error{{unknown type}}
166+
static void f10(void) { unreachable(); }
167+
max_align_t m10;
168+
size_t o10 = offsetof(struct astruct, member);
169+
wint_t wi10;

0 commit comments

Comments
 (0)