*===-----------------------------------------------------------------------===
*/
-#ifndef __STDDEF_H
+#if !defined(__STDDEF_H) || 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_wchar_t) && !defined(__need_NULL) && \
+ !defined(__need_wint_t)
#define __STDDEF_H
+#define __need_ptrdiff_t
+#define __need_size_t
+#define __need_wchar_t
+#define __need_NULL
+/* __need_wint_t is intentionally not defined here. */
+#endif
+#if defined(__need_ptrdiff_t)
#if !defined(_PTRDIFF_T) || __has_feature(modules)
/* Always define ptrdiff_t when modules are available. */
#if !__has_feature(modules)
#endif
typedef __PTRDIFF_TYPE__ ptrdiff_t;
#endif
+#undef __need_ptrdiff_t
+#endif /* defined(__need_ptrdiff_t) */
+#if defined(__need_size_t)
#if !defined(_SIZE_T) || __has_feature(modules)
/* Always define size_t when modules are available. */
#if !__has_feature(modules)
#endif
typedef __SIZE_TYPE__ size_t;
#endif
+#undef __need_size_t
+#endif /*defined(__need_size_t) */
+#if defined(__STDDEF_H)
/* 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 && \
#endif
typedef __SIZE_TYPE__ rsize_t;
#endif
+#endif /* defined(__STDDEF_H) */
+#if defined(__need_wchar_t)
#ifndef __cplusplus
/* Always define wchar_t when modules are available. */
#if !defined(_WCHAR_T) || __has_feature(modules)
typedef __WCHAR_TYPE__ wchar_t;
#endif
#endif
+#undef __need_wchar_t
+#endif /* defined(__need_wchar_t) */
+#if defined(__need_NULL)
#undef NULL
#ifdef __cplusplus
# if !defined(__MINGW32__) && !defined(_MSC_VER)
#else
# define NULL ((void*)0)
#endif
-
#ifdef __cplusplus
#if defined(_MSC_EXTENSIONS) && defined(_NATIVE_NULLPTR_SUPPORTED)
namespace std { typedef decltype(nullptr) nullptr_t; }
using ::std::nullptr_t;
#endif
#endif
+#undef __need_NULL
+#endif /* defined(__need_NULL) */
+
+#if defined(__STDDEF_H)
#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L
+#if !defined(__CLANG_MAX_ALIGN_T_DEFINED) || __has_feature(modules)
#ifndef _MSC_VER
typedef struct {
long long __clang_max_align_nonce1
#endif
#define __CLANG_MAX_ALIGN_T_DEFINED
#endif
+#endif
#define offsetof(t, d) __builtin_offsetof(t, d)
-
-#endif /* __STDDEF_H */
+#endif /* __STDDEF_H */
/* 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 */
#endif
#undef __need_wint_t
#endif /* __need_wint_t */
+
+#endif
--- /dev/null
+// RUN: %clang_cc1 -fsyntax-only -verify -Wsentinel -std=c++11 %s
+
+ptrdiff_t p0; // expected-error{{unknown}}
+size_t s0; // expected-error{{unknown}}
+void* v0 = NULL; // expected-error{{undeclared}}
+wint_t w0; // expected-error{{unknown}}
+max_align_t m0; // expected-error{{unknown}}
+
+#define __need_ptrdiff_t
+#include <stddef.h>
+
+ptrdiff_t p1;
+size_t s1; // expected-error{{unknown}}
+void* v1 = NULL; // expected-error{{undeclared}}
+wint_t w1; // expected-error{{unknown}}
+max_align_t m1; // expected-error{{unknown}}
+
+#define __need_size_t
+#include <stddef.h>
+
+ptrdiff_t p2;
+size_t s2;
+void* v2 = NULL; // expected-error{{undeclared}}
+wint_t w2; // expected-error{{unknown}}
+max_align_t m2; // expected-error{{unknown}}
+
+#define __need_NULL
+#include <stddef.h>
+
+ptrdiff_t p3;
+size_t s3;
+void* v3 = NULL;
+wint_t w3; // expected-error{{unknown}}
+max_align_t m3; // expected-error{{unknown}}
+
+// Shouldn't bring in wint_t by default:
+#include <stddef.h>
+
+ptrdiff_t p4;
+size_t s4;
+void* v4 = NULL;
+wint_t w4; // expected-error{{unknown}}
+max_align_t m4;
+
+#define __need_wint_t
+#include <stddef.h>
+
+ptrdiff_t p5;
+size_t s5;
+void* v5 = NULL;
+wint_t w5;
+max_align_t m5;
+
+
+// linux/stddef.h does something like this for cpp files:
+#undef NULL
+#define NULL 0
+
+// glibc (and other) headers then define __need_NULL and rely on stddef.h
+// to redefine NULL to the correct value again.
+#define __need_NULL
+#include <stddef.h>
+
+// gtk headers then use __attribute__((sentinel)), which doesn't work if NULL
+// is 0.
+void f(const char* c, ...) __attribute__((sentinel));
+void g() {
+ f("", NULL); // Shouldn't warn.
+}