[clang] [clang][headers] Including stddef.h always redefines NULL (PR #99727)

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 22 13:43:52 PDT 2024


================
@@ -49,7 +48,24 @@
 #define __need_rsize_t
 #endif
 #define __need_wchar_t
+#if !defined(__STDDEF_H) || __has_feature(modules)
+/*
+ * __stddef_null.h is special when building without modules: if __need_NULL is
+ * set, then it will unconditionally redefine NULL. To avoid stepping on client
+ * definitions of NULL, __need_NULL should only be set the first time this
+ * header is included, that is when __STDDEF_H is not defined. However, when
+ * building with modules, this header is a textual header and needs to
+ * unconditionally include __stdef_null.h to support multiple submodules
+ * exporting _Builtin_stddef.null. Take module SM with submodules A and B, whose
+ * headers both include stddef.h When SM.A builds, __STDDEF_H will be defined.
+ * When SM.B builds, the definition from SM.A will leak when building without
+ * local submodule visibility. stddef.h wouldn't include __stddef_null.h, and
+ * SM.B wouldn't import _Builtin_stddef.null, and SM.B's `export *` wouldn't
+ * export NULL as expected. When building with modules, always include
+ * __stddef_null.h so that everything works as expected.
+ */
 #define __need_NULL
+#endif
----------------
zygoloid wrote:

This change now looks like a (fairly trivial, but still) regression for local submodule visibility mode. In particular:
```c++
#include <stddef.h>
#undef NULL
#include <stddef.h>
```
is supposed to leave `NULL` undefined, but won't do so any more.

Perhaps we should introduce a feature test macro for "no local submodule visibility" mode ("name leakage between submodules" mode?) so that workarounds for the infelicities of that mode remain scoped to it?

https://github.com/llvm/llvm-project/pull/99727


More information about the cfe-commits mailing list