Skip to content

[cherry-pick stable/20230725] [Headers] Replace __need_STDDEF_H_misc with specific __need_ macros #7615

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 57 additions & 30 deletions clang/lib/Headers/stddef.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,48 @@
*/

#if !defined(__STDDEF_H) || defined(__need_ptrdiff_t) || \
defined(__need_size_t) || defined(__need_wchar_t) || \
defined(__need_NULL) || defined(__need_wint_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) || \
(defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1)

#if !defined(__need_ptrdiff_t) && !defined(__need_size_t) && \
!defined(__need_wchar_t) && !defined(__need_NULL) && \
!defined(__need_wint_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)
/* Always define miscellaneous pieces when modules are available. */
#if !__has_feature(modules)
#define __STDDEF_H
#endif
#define __need_ptrdiff_t
#define __need_size_t
/* ISO9899:2011 7.20 (C11 Annex K): Define rsize_t if __STDC_WANT_LIB_EXT1__ is
* enabled. */
#if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1
#define __need_rsize_t
#endif
#define __need_wchar_t
#define __need_NULL
#define __need_STDDEF_H_misc
/* __need_wint_t is intentionally not defined here. */
/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L) || \
defined(__cplusplus)
#define __need_nullptr_t
#endif
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#define __need_unreachable
#endif
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
(defined(__cplusplus) && __cplusplus >= 201103L)
#define __need_max_align_t
#endif
#define __need_offsetof
/* wint_t is provided by <wchar.h> and not <stddef.h>. It's here
* for compatibility, but must be explicitly requested. Therefore
* __need_wint_t is intentionally not defined here. */
#endif

#if defined(__need_ptrdiff_t)
Expand All @@ -48,18 +74,16 @@ typedef __SIZE_TYPE__ size_t;
#undef __need_size_t
#endif /*defined(__need_size_t) */

#if defined(__need_STDDEF_H_misc)
/* ISO9899:2011 7.20 (C11 Annex K): Define rsize_t if __STDC_WANT_LIB_EXT1__ is
* enabled. */
#if (defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1 && \
!defined(_RSIZE_T)) || __has_feature(modules)
#if defined(__need_rsize_t)
#if !defined(_RSIZE_T) || __has_feature(modules)
/* Always define rsize_t when modules are available. */
#if !__has_feature(modules)
#define _RSIZE_T
#endif
typedef __SIZE_TYPE__ rsize_t;
#endif
#endif /* defined(__need_STDDEF_H_misc) */
#undef __need_rsize_t
#endif /* defined(__need_rsize_t) */

#if defined(__need_wchar_t)
#if !defined(__cplusplus) || (defined(_MSC_VER) && !_NATIVE_WCHAR_T_DEFINED)
Expand Down Expand Up @@ -88,34 +112,37 @@ typedef __WCHAR_TYPE__ wchar_t;
#else
# define NULL ((void*)0)
#endif
#undef __need_NULL
#endif /* defined(__need_NULL) */

#if defined(__need_nullptr_t)
#ifdef __cplusplus
#if defined(_MSC_EXTENSIONS) && defined(_NATIVE_NULLPTR_SUPPORTED)
namespace std { typedef decltype(nullptr) nullptr_t; }
namespace std {
typedef decltype(nullptr) nullptr_t;
}
using ::std::nullptr_t;
#endif
#endif
#undef __need_NULL
#endif /* defined(__need_NULL) */

/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#else
typedef typeof(nullptr) nullptr_t;
#endif /* defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L */
#endif
#undef __need_nullptr_t
#endif /* defined(__need_nullptr_t) */

#if defined(__need_STDDEF_H_misc) && defined(__STDC_VERSION__) && \
__STDC_VERSION__ >= 202000L
#if defined(__need_unreachable)
#define unreachable() __builtin_unreachable()
#endif /* defined(__need_STDDEF_H_misc) && >= C23 */
#undef __need_unreachable
#endif /* defined(__need_unreachable) */

#if defined(__need_STDDEF_H_misc)
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
(defined(__cplusplus) && __cplusplus >= 201103L)
#if defined(__need_max_align_t)
#include "__stddef_max_align_t.h"
#endif
#undef __need_max_align_t
#endif /* defined(__need_max_align_t) */

#if defined(__need_offsetof)
#define offsetof(t, d) __builtin_offsetof(t, d)
#undef __need_STDDEF_H_misc
#endif /* defined(__need_STDDEF_H_misc) */
#undef __need_offsetof
#endif /* defined(__need_offsetof) */

/* Some C libraries expect to see a wint_t here. Others (notably MinGW) will use
__WINT_TYPE__ directly; accommodate both by requiring __need_wint_t */
Expand Down
46 changes: 46 additions & 0 deletions clang/test/Headers/stddef.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// RUN: %clang_cc1 -fsyntax-only -verify=c99 -std=c99 %s
// RUN: %clang_cc1 -fsyntax-only -verify=c11 -std=c11 %s
// RUN: %clang_cc1 -fsyntax-only -verify=c23 -std=c23 %s

struct astruct { char member; };

ptrdiff_t p0; // c99-error{{unknown type name 'ptrdiff_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
size_t s0; // c99-error{{unknown type name 'size_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
rsize_t r0; // c99-error{{unknown type name 'rsize_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
wchar_t wc0; // c99-error{{unknown type name 'wchar_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
void *v0 = NULL; // c99-error{{use of undeclared identifier 'NULL'}} c11-error{{undeclared identifier}} c23-error{{undeclared identifier}}
nullptr_t n0; // c99-error{{unknown type name 'nullptr_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
static void f0(void) { unreachable(); } // c99-error{{call to undeclared function 'unreachable'}} c11-error{{undeclared function}} c23-error{{undeclared identifier}}
max_align_t m0; // c99-error{{unknown type name 'max_align_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
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'}} \
c11-error{{unknown type}} c11-error{{undeclared function}} c11-error{{expected expression}} c11-error{{undeclared identifier}} \
c23-error{{unknown type}} c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
wint_t wi0; // c99-error{{unknown type name 'wint_t'}} c11-error{{unknown type}} c23-error{{unknown type}}

#include <stddef.h>

ptrdiff_t p1;
size_t s1;
rsize_t r1; // c99-error{{unknown type}} c11-error{{unknown type}} c23-error{{unknown type}}
// [email protected]:*{{'size_t' declared here}} [email protected]:*{{'size_t' declared here}} [email protected]:*{{'size_t' declared here}}
wchar_t wc1;
void *v1 = NULL;
nullptr_t n1; // c99-error{{unknown type}} c11-error{{unknown type}}
static void f1(void) { unreachable(); } // c99-error{{undeclared function}} c11-error{{undeclared function}}
max_align_t m1; // c99-error{{unknown type}}
size_t o1 = offsetof(struct astruct, member);
wint_t wi1; // c99-error{{unknown type}} c11-error{{unknown type}} c23-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; // c99-error{{unknown type}} c11-error{{unknown type}}
static void f2(void) { unreachable(); } // c99-error{{undeclared function}} c11-error{{undeclared function}}
max_align_t m2; // c99-error{{unknown type}}
size_t o2 = offsetof(struct astruct, member);
wint_t wi2; // c99-error{{unknown type}} c11-error{{unknown type}} c23-error{{unknown type}}
169 changes: 169 additions & 0 deletions clang/test/Headers/stddefneeds.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
// RUN: %clang_cc1 -fsyntax-only -verify=c99 -std=c99 %s
// RUN: %clang_cc1 -fsyntax-only -verify=c23 -std=c23 %s

// Use C99 to verify that __need_ can be used to get types that wouldn't normally be available.

struct astruct { char member; };

ptrdiff_t p0; // c99-error{{unknown type name 'ptrdiff_t'}} c23-error{{unknown type}}
size_t s0; // c99-error{{unknown type name 'size_t'}} c23-error{{unknown type}}
rsize_t r0; // c99-error{{unknown type name 'rsize_t'}} c23-error{{unknown type}}
wchar_t wc0; // c99-error{{unknown type name 'wchar_t'}} c23-error{{unknown type}}
void *v0 = NULL; // c99-error{{use of undeclared identifier 'NULL'}} c23-error{{undeclared identifier}}
nullptr_t n0; // c99-error{{unknown type name 'nullptr_t'}} c23-error{{unknown type}}
static void f0(void) { unreachable(); } // c99-error{{call to undeclared function 'unreachable'}} c23-error{{undeclared identifier 'unreachable'}}
max_align_t m0; // c99-error{{unknown type name 'max_align_t'}} c23-error{{unknown type}}
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'}} \
c23-error{{unknown type name 'size_t'}} c23-error{{undeclared identifier 'offsetof'}} c23-error{{expected expression}} c23-error{{use of undeclared identifier 'member'}}
wint_t wi0; // c99-error{{unknown type name 'wint_t'}} c23-error{{unknown type}}

#define __need_ptrdiff_t
#include <stddef.h>

ptrdiff_t p1;
size_t s1; // c99-error{{unknown type}} c23-error{{unknown type}}
rsize_t r1; // c99-error{{unknown type}} c23-error{{unknown type}}
wchar_t wc1; // c99-error{{unknown type}} c23-error{{unknown type}}
void *v1 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}}
nullptr_t n1; // c99-error{{unknown type}} c23-error{{unknown type}}
static void f1(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}}
max_align_t m1; // c99-error{{unknown type}} c23-error{{unknown type}}
size_t o1 = offsetof(struct astruct, member); // c99-error{{unknown type}} c99-error{{expected expression}} c99-error{{undeclared identifier}} \
c23-error{{unknown type}} c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
wint_t wi1; // c99-error{{unknown type}} c23-error{{unknown type}}

#define __need_size_t
#include <stddef.h>

ptrdiff_t p2;
size_t s2;
rsize_t r2; // c99-error{{unknown type}} c23-error{{unknown type}}
// [email protected]:*{{'size_t' declared here}} [email protected]:*{{'size_t' declared here}}
wchar_t wc2; // c99-error{{unknown type}} c23-error{{unknown type}}
void *v2 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}}
nullptr_t n2; // c99-error{{unknown type}} c23-error{{unknown type}}
static void f2(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}}
max_align_t m2; // c99-error{{unknown type}} c23-error{{unknown type}}
size_t o2 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
wint_t wi2; // c99-error{{unknown type}} c23-error{{unknown type}}

#define __need_rsize_t
#include <stddef.h>

ptrdiff_t p3;
size_t s3;
rsize_t r3;
wchar_t wc3; // c99-error{{unknown type}} c23-error{{unknown type}}
void *v3 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}}
nullptr_t n3; // c99-error{{unknown type}} c23-error{{unknown type}}
static void f3(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}}
max_align_t m3; // c99-error{{unknown type}} c23-error{{unknown type}}
size_t o3 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
wint_t wi3; // c99-error{{unknown type}} c23-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; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}}
nullptr_t n4; // c99-error{{unknown type}} c23-error{{unknown type}}
static void f4(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}}
max_align_t m4; // c99-error{{unknown type}} c23-error{{unknown type}}
size_t o4 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
wint_t wi4; // c99-error{{unknown type}} c23-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; // c99-error{{unknown type}} c23-error{{unknown type}}
static void f5(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}}
max_align_t m5; // c99-error{{unknown type}} c23-error{{unknown type}}
size_t o5 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
wint_t wi5; // c99-error{{unknown type}} c23-error{{unknown type}}

// __need_nullptr_t generates an error in <C23 because its definition
// depends on nullptr.
#define __need_nullptr_t
#include <stddef.h> // [email protected]:*{{expected function body}}

ptrdiff_t p6;
size_t s6;
rsize_t r6;
wchar_t wc6;
void *v6 = NULL;
nullptr_t n6; // c99-error{{unknown type}}
static void f6(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}}
max_align_t m6; // c99-error{{unknown type}} c23-error{{unknown type}}
size_t o6 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
wint_t wi6; // c99-error{{unknown type}} c23-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 ; // c99-error{{unknown type}}
static void f7(void) { unreachable(); }
max_align_t m7; // c99-error{{unknown type}} c23-error{{unknown type}}
size_t o7 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
wint_t wi7; // c99-error{{unknown type}} c23-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; // c99-error{{unknown type}}
static void f8(void) { unreachable(); }
max_align_t m8;
size_t o8 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
wint_t wi8; // c99-error{{unknown type}} c23-error{{unknown type}}

#define __need_offsetof
#include <stddef.h>

ptrdiff_t p9;
size_t s9;
rsize_t r9;
nullptr_t n9; // c99-error{{unknown type}}
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; // c99-error{{unknown type}} c23-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; // c99-error{{unknown type}}
static void f10(void) { unreachable(); }
max_align_t m10;
size_t o10 = offsetof(struct astruct, member);
wint_t wi10;