diff --git a/clang-tools-extra/clang-include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp b/clang-tools-extra/clang-include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp --- a/clang-tools-extra/clang-include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp +++ b/clang-tools-extra/clang-include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp @@ -14,6 +14,7 @@ const HeaderMapCollector::RegexHeaderMap *getSTLPostfixHeaderMap() { static const HeaderMapCollector::RegexHeaderMap STLPostfixHeaderMap = { {"include/__stddef_max_align_t.h$", ""}, + {"include/__stddef_null.h$", ""}, {"include/__wmmintrin_aes.h$", ""}, {"include/__wmmintrin_pclmul.h$", ""}, {"include/adxintrin.h$", ""}, diff --git a/clang-tools-extra/clangd/index/CanonicalIncludes.cpp b/clang-tools-extra/clangd/index/CanonicalIncludes.cpp --- a/clang-tools-extra/clangd/index/CanonicalIncludes.cpp +++ b/clang-tools-extra/clangd/index/CanonicalIncludes.cpp @@ -20,6 +20,7 @@ namespace { const std::pair IncludeMappings[] = { {"include/__stddef_max_align_t.h", ""}, + {"include/__stddef_null.h", ""}, {"include/__wmmintrin_aes.h", ""}, {"include/__wmmintrin_pclmul.h", ""}, {"include/adxintrin.h", ""}, diff --git a/clang/docs/tools/clang-formatted-files.txt b/clang/docs/tools/clang-formatted-files.txt --- a/clang/docs/tools/clang-formatted-files.txt +++ b/clang/docs/tools/clang-formatted-files.txt @@ -492,6 +492,7 @@ clang/lib/Headers/__clang_cuda_texture_intrinsics.h clang/lib/Headers/__clang_hip_libdevice_declares.h clang/lib/Headers/__stddef_max_align_t.h +clang/lib/Headers/__stddef_null.h clang/lib/Headers/openmp_wrappers/complex.h clang/lib/Headers/openmp_wrappers/complex_cmath.h clang/lib/Headers/openmp_wrappers/math.h diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp --- a/clang/lib/Basic/Module.cpp +++ b/clang/lib/Basic/Module.cpp @@ -298,8 +298,9 @@ if (Requested->isSubModuleOf(Use)) return true; - // Anyone is allowed to use our builtin stddef.h and its accompanying module. - if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") + // Anyone is allowed to use our builtin stddef.h and its accompanying modules. + if (!Requested->Parent && (Requested->Name == "_Builtin_stddef_max_align_t" || + Requested->Name == "_Builtin_stddef_null")) return true; if (NoUndeclaredIncludes) diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -14,6 +14,7 @@ stdbool.h stddef.h __stddef_max_align_t.h + __stddef_null.h stdint.h stdnoreturn.h tgmath.h diff --git a/clang/lib/Headers/__stddef_null.h b/clang/lib/Headers/__stddef_null.h new file mode 100644 --- /dev/null +++ b/clang/lib/Headers/__stddef_null.h @@ -0,0 +1,35 @@ +/*===---- __stddef_null.h - Definition of NULL -----------------------------=== + * + * 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 + * + *===-----------------------------------------------------------------------=== + */ + +#if !defined(__STDDEF_NULL_H) || defined(__need_NULL) + +#ifndef __STDDEF_NULL_H +#define __STDDEF_NULL_H +#endif + +#undef NULL +#ifdef __cplusplus +#if !defined(__MINGW32__) && !defined(_MSC_VER) +#define NULL __null +#else +#define NULL 0 +#endif +#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 + +#endif diff --git a/clang/lib/Headers/module.modulemap b/clang/lib/Headers/module.modulemap --- a/clang/lib/Headers/module.modulemap +++ b/clang/lib/Headers/module.modulemap @@ -157,6 +157,11 @@ header "__stddef_max_align_t.h" } +module _Builtin_stddef_null [system] { + header "__stddef_null.h" + export * +} + module opencl_c { requires opencl header "opencl-c.h" diff --git a/clang/lib/Headers/stddef.h b/clang/lib/Headers/stddef.h --- a/clang/lib/Headers/stddef.h +++ b/clang/lib/Headers/stddef.h @@ -78,22 +78,7 @@ #endif /* defined(__need_wchar_t) */ #if defined(__need_NULL) -#undef NULL -#ifdef __cplusplus -# if !defined(__MINGW32__) && !defined(_MSC_VER) -# define NULL __null -# else -# define NULL 0 -# endif -#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 +#include <__stddef_null.h> #undef __need_NULL #endif /* defined(__need_NULL) */ diff --git a/clang/test/Headers/stddef_null.cpp b/clang/test/Headers/stddef_null.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Headers/stddef_null.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-macosx10.9.0 -verify -Wsentinel -std=c++11 %s + +void *v0 = NULL; // expected-error{{undeclared}} + +// Shouldn't bring in anything else from stddef.h +#include <__stddef_null.h> +void *v1 = NULL; +ptrdiff_t p1; // expected-error{{unknown}} +size_t s1; // expected-error{{unknown}} +wint_t w1; // expected-error{{unknown}} +max_align_t m1; // expected-error{{unknown}} + + +// 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_null.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. +} diff --git a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h --- a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h +++ b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h @@ -20,6 +20,7 @@ #include #include // IWYU pragma: no_include <__stddef_max_align_t.h> +// IWYU pragma: no_include <__stddef_null.h> namespace gwp_asan { // This class is the primary implementation of the allocator portion of GWP- diff --git a/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn --- a/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn @@ -88,6 +88,7 @@ "__clang_hip_runtime_wrapper.h", "__clang_hip_stdlib.h", "__stddef_max_align_t.h", + "__stddef_null.h", "__wmmintrin_aes.h", "__wmmintrin_pclmul.h", "adxintrin.h",