Skip to content

[libc++] stddef.h needs to #include_next for the new clang __need_ macros #86252

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

Closed

Conversation

ian-twilightcoder
Copy link
Contributor

@ian-twilightcoder ian-twilightcoder commented Mar 22, 2024

clang added several __need_ macros to stddef.h that need to be added to the libc++ version as well. clang will also re-enter stddef.h to define rsize_t if __STDC_WANT_LIB_EXT1__ is set, do that in the libc++ one too.

@ian-twilightcoder ian-twilightcoder requested a review from a team as a code owner March 22, 2024 06:47
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Mar 22, 2024
@llvmbot
Copy link
Member

llvmbot commented Mar 22, 2024

@llvm/pr-subscribers-libcxx

Author: Ian Anderson (ian-twilightcoder)

Changes

clang added several _need macros to stddef.h that need to be added to the libc++ version as well. clang will also re-enter stddef.h to define rsize_t if STDC_WANT_LIB_EXT1 is set, do that in the libc++ one too.


Full diff: https://github.com/llvm/llvm-project/pull/86252.diff

1 Files Affected:

  • (modified) libcxx/include/stddef.h (+4-3)
diff --git a/libcxx/include/stddef.h b/libcxx/include/stddef.h
index 887776b150e49d..a3acf0ff10d1b6 100644
--- a/libcxx/include/stddef.h
+++ b/libcxx/include/stddef.h
@@ -7,8 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#if 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_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)
 
 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #    pragma GCC system_header
@@ -16,7 +17,7 @@
 
 #  include_next <stddef.h>
 
-#elif !defined(_LIBCPP_STDDEF_H)
+#elif !defined(_LIBCPP_STDDEF_H) || (defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1)
 #  define _LIBCPP_STDDEF_H
 
 /*

@ldionne
Copy link
Member

ldionne commented Mar 23, 2024

These macros are obscure. I would, in fact, much rather remove any knowledge of __need_ macros from our headers.

@ian-twilightcoder
Copy link
Contributor Author

These macros are obscure. I would, in fact, much rather remove any knowledge of __need_ macros from our headers.

I guess we could try removing the macros and the header guard and just always include_next. That feels like a riskier change for llvm 18 though.

@ian-twilightcoder
Copy link
Contributor Author

ian-twilightcoder commented Mar 23, 2024

These macros are obscure. I would, in fact, much rather remove any knowledge of __need_ macros from our headers.

I guess we could try removing the macros and the header guard and just always include_next. That feels like a riskier change for llvm 18 though.

Which is to say I'd rather do the safe thing right now and leave this PR the way it is, which is just to fixup the way this header already works rather than try to clean it up. At least for this release, if that's ok with you.

@ian-twilightcoder ian-twilightcoder force-pushed the cxx-stdarg-stddef branch 2 times, most recently from 3859239 to f9a477c Compare March 25, 2024 21:31
@llvm llvm deleted a comment from github-actions bot Mar 25, 2024
@llvm llvm deleted a comment from github-actions bot Mar 25, 2024
@llvm llvm deleted a comment from github-actions bot Mar 25, 2024
@llvm llvm deleted a comment from github-actions bot Mar 25, 2024
@ian-twilightcoder ian-twilightcoder force-pushed the cxx-stdarg-stddef branch 2 times, most recently from 3d2fb6a to 7cb02ca Compare March 25, 2024 22:56
@llvm llvm deleted a comment from github-actions bot Mar 25, 2024
@llvm llvm deleted a comment from github-actions bot Mar 25, 2024
@@ -7,16 +7,27 @@
//
//===----------------------------------------------------------------------===//

#if 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_rsize_t) || defined(__need_wchar_t) || \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would actually suggest that we change the whole header to this:

// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

/*
    stddef.h synopsis

Macros:

    offsetof(type,member-designator)
    NULL

Types:

    ptrdiff_t
    size_t
    max_align_t // C++11
    nullptr_t

*/

#include <__config>

// Note: This include is outside of header guards because we sometimes get included multiple times
//       with different defines and the underlying <stddef.h> will know how to deal with that.
#include_next <stddef.h>

#ifndef _LIBCPP_STDDEF_H
#  define _LIBCPP_STDDEF_H

#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#    pragma GCC system_header
#  endif

#  ifdef __cplusplus
typedef decltype(nullptr) nullptr_t;
#  endif

#endif // _LIBCPP_STDDEF_H

WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can unconditionally declare nullptr_t. If e.g. __need_size_t is set, then nullptr_t shouldn't get declared. I'm not sure if that's for POSIX conformance or what, but it seems to be important when I talk to people implementing low level headers.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see what the problem would be though? We'd be defining it at most once due to the header guard, and nobody else anywhere should be defining nullptr_t anyways.

Either way, I can try doing that in a separate patch.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I officially don't understand this patch anymore so I would argue we should go for the simpler approach suggested above unless there's a concrete reason why that wouldn't work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that some headers need to declare just size_t, and it's a problem if anything else gets declared. The way they do that is by setting __need_size_t and including stddef.h. I think it's for POSIX reasons but I'm not 100% why it's so important for people to be able to only see pieces of stdarg and stddef.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AaronBallman do you know why the __need_ macros are so important in the clang stddef.h?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding is that this is needed for interfacing with other CRTs (primarily Apple's?):
https://opensource.apple.com/source/Libc/Libc-825.26/include/stddef.h.auto.html
https://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20151005/140394.html

and was carried forward with newer functionality more recently:
https://reviews.llvm.org/D157757

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for digging this up. We're checking with some folks internally.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The answer we're getting from the Darwin folks is that they can't find a historical reason for it. Basically our current understanding is that on Darwin at least, the most naive implementation (without any __need_FOO macros) should work. Or at least it would be intended to work.

I don't know about Linuxes though. At the very least, as far as libc++ is concerned, I am quite tempted to close this PR and go with #86843 instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No one's really sure why it's important for the __need_ macros to be perfectly strict. Trying out #86843 internally. We're still talking about if we want to keep this PR for the tests and copy stddef.h from that one, or dump the tests and just do 86843 by itself.

Copy link

github-actions bot commented Mar 27, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@ian-twilightcoder ian-twilightcoder force-pushed the cxx-stdarg-stddef branch 2 times, most recently from 9ccc7cd to 80f1c8d Compare March 27, 2024 04:26
…cros

clang added several __need_ macros to stddef.h that need to be added to the libc++ version as well. clang will also re-enter stddef.h to define rsize_t if __STDC_WANT_LIB_EXT1__ is set, do that in the libc++ one too.
@ldionne
Copy link
Member

ldionne commented Apr 2, 2024

We tried out #86843 internally and it did fix the problem we had encountered. Since it's simpler, I'm closing this PR in favor of #86843.

@ldionne ldionne closed this Apr 2, 2024
@ian-twilightcoder ian-twilightcoder deleted the cxx-stdarg-stddef branch April 10, 2024 19:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants