This requires the __builtin_source_location() builtin, as implemented
by GCC and Clang.
Details
- Reviewers
ldionne philnik - Group Reviewers
Restricted Project - Commits
- rG73d94b191613: [Libcxx] Add <source_location> header.
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
FWIW, you can maybe check if there is any test (or anything else) to take from https://reviews.llvm.org/D80376 (my failed attempt to implement this, but without clang's built-in).
Looks like you have to run ninja libcxx-generate-files.
libcxx/include/source_location | ||
---|---|---|
41 | ||
44–45 | ||
64–75 | ||
78 | ||
libcxx/test/std/language.support/support.srcloc/general.pass.cpp | ||
17–20 | This should be something along the lines of // UNSUPPORTED: clang-13, depending on when __builtin_source_location was implemented. |
You also have to add the header to libcxx/include/modules.modulemap and libcxx/include/CMakeLists.txt.
libcxx/include/version | ||
---|---|---|
361–364 | You should edit libcxx/utils/generate_feature_test_macro_components.py. This is a generated file. |
+1 to all @philnik's comments. Looks pretty decent otherwise; let's see what buildkite thinks of it!
libcxx/test/std/language.support/support.srcloc/general.pass.cpp | ||
---|---|---|
12–15 | ||
44 | By convention (something about freestanding support): int main(int, char**) { |
Thanks for working on this! Some additional comments.
libcxx/include/source_location | ||
---|---|---|
12 | Please update the source_location status in docs/Cxx2aStatusPaperStatus.csv. Look like this implements both both P1208 and LWG-3396. | |
29 | This header needs to be included in all library header, it provides all important macros like _LIBCPP_BEGIN_NAMESPACE_STD. | |
56 | The __ptr argument differs from the wording in the Standard, can you add comment why this is done? | |
libcxx/test/std/language.support/support.srcloc/general.pass.cpp | ||
17–20 | Since the clang part is under review it should be also unsupported in clang-13 and apple-clang-12. |
Done.
Done.
libcxx/include/source_location | ||
---|---|---|
31–32 | I'd like a reviewer to opine on this question here. | |
libcxx/test/std/language.support/support.srcloc/general.pass.cpp | ||
17–20 | Well, it's not implemented until the patch this depends on. So it'll be implemented as of clang-15 -- but current builds of clang-15 don't have that support. Should I just put "// UNSUPPORTED: clang-13, clang-14"? Will that cause problems with test-bots? I'll submit the other patch first -- but do libcxx bots run with older builds of unreleased head clang? Guess I'll just try and see what happens... |
So, in doing further testing, I've noticed a problem. Currently, clang cannot compile code that calls a consteval function in a default argument. (see https://github.com/llvm/llvm-project/issues/48230 and https://reviews.llvm.org/D119646)
E.g., clang -std=c++20 -fsyntax-only consteval.cc given:
consteval int foo() { return 1; } int bar(int N = foo()) { return N; } int main() { return bar(); }
raises "error: cannot take address of consteval function 'foo' outside of an immediate invocation", incorrectly.
The same issue occurs with the consteval std::source_location::current() -- which makes it effectively impossible to use std::source_location::current() as it's intended to be used, in a default-argument.
libcxx/include/source_location | ||
---|---|---|
31–32 | IMHO #include <cstdint> is fine (but please move it up with the others and alphabetize). | |
44–45 | Nit: s/REQUIRED/required/ (the emphasis is unnecessary, and potentially briefly confusing in that REQUIRED has a special meaning in tests). I might reword this comment as // The names source_location::__impl, _M_file_name, _M_function_name, _M_line, and _M_column // are hard-coded in the compiler and must not be changed here. (Note for users of git grep: These names are not hard-coded in Clang yet; they're part of D120159 which has not yet landed.) | |
58–59 | My kneejerk reaction here was "this indentation is messed up," but then my eyes refocused. ;) static consteval source_location current(const void *__ptr = __builtin_source_location()) noexcept { Using const void * instead of decltype(__builtin_source_location()) helps readability and doesn't seem to hurt anything since you're already doing the cast on line 61. In fact, at that point I'd remove the comment on line 60 because now the cast isn't unusual-looking at all. (2) Should we use _LIBCPP_HIDE_FROM_ABI here, even though it's consteval? I don't know. | |
libcxx/utils/generate_feature_test_macro_components.py | ||
636–642 | Please git grep source_location ../libcxx/docs/ and see whether you can check off any relevant papers or issues. (Also of course git grep source_location ../libcxx in general.) |
libcxx/include/source_location | ||
---|---|---|
58–59 |
I don't think so. A consteval function can never be part of any ABI, so there is no need to mark it as _LIBCPP_HIDE_FOM_ABI. |
libcxx/include/source_location | ||
---|---|---|
58–59 | I don't think using const void* improves readability. Why do you say that? @Quuxplusone Going forward the project should take a "format and forget about it" approach to whitespace changes. What's correct is what clang-format spits out. I don't believe reviewing whitespace changes is a good use of engineering effort. | |
65 | When does this constructor get called? I assume it's in the spec? |
libcxx/test/std/language.support/support.srcloc/general.pass.cpp | ||
---|---|---|
17–20 |
The CI uses nightly Ubuntu builds, but the Docker file isn't automatically updated. This means:
This isn't ideal, but we've used this approach for other patches with dependencies on the CI running the latest version of our Docker file. |
Does this mean we'll only implement source_location with Clang? Or does GCC provide a similar builtin? If so, are both compatible?
libcxx/include/source_location | ||
---|---|---|
31–32 | Yeah, I'd rather use uint_least32_t and include the header than use the more arcane __UINT_LEAST32_TYPE__. | |
58–59 | We've had numerous discussions about clang-format in the past several months. Please consult the Discord archive for details, but long story short, the current state of things is that we're going to first agree on a clang-format configuration that is suitable, and then slowly move towards it for new code. It hasn't happened yet. Regarding decltype(__builtin_source_location()), you could also just use auto* instead. | |
libcxx/test/std/language.support/support.srcloc/general.pass.cpp | ||
17–20 | @Mordante is correct -- basically we'll need to wait a bit after the Clang patch lands for the Docker images to be refreshed and then all CI will be running with a Clang that supports the builtin. In the meantime, only the Bootstraping build bot would is relevant, since it's the only one that's going to run this test. | |
33 | I'd like us to test the return type of all these functions. We usually do something like std::same_as<uint_least32_t> auto line = empty.line();. |
libcxx/include/source_location | ||
---|---|---|
58–59 | Fantastic. Let's do that. Because reviewing whitespace is in nobodys best interest. |
libcxx/include/source_location | ||
---|---|---|
58–59 | Can't use auto* in the argument type -- that'd make this into a function template. I don't want to use a const void * argument, because constexprs are not allowed to cast back _from_ void*, even if the underlying object is a T and you're casting to T*. (However, note that I did add a hack to Clang to support libstdc++ -- which DOES have that invalid cast that GCC doesn't diagnose, but I wouldn't want to introduce the same issue into libc++.) I can move the decltype into a separate using __bsl_ty = decltype(__builtin_source_location()); line to improve readability. | |
65 | Not sure what you mean. Yes, a default constructor is required by the spec. | |
libcxx/test/std/language.support/support.srcloc/general.pass.cpp | ||
17–20 | The GCC bot should be running the test already. Are you sure the bootstrapping build is doing this? Because if so, it should've failed (as clang-15 isn't marked unsupported), but it didn't. | |
libcxx/utils/generate_feature_test_macro_components.py | ||
636–642 | Did that already in the preceding update. |
LGTM. I might make a minor pass on the test to make it look more like our other tests (in particular try to avoid duplication of constexpr and non-constexpr tests), but overall this LGTM.
Thanks a whole lot for working on this, we really needed someone to step up and implement this with the help of the compiler.
libcxx/test/std/language.support/support.srcloc/general.pass.cpp | ||
---|---|---|
17–20 | Yes, I am sure the bootstrapping build is running with the just-built Clang. Is it possible that CI ran alongside with the parent commit too? I think that's how it works. |
libcxx/test/std/language.support/support.srcloc/general.pass.cpp | ||
---|---|---|
66 | Too bad we can't std::string_view(local.function_name()).contains("main") until C++23. :( +1 for assert(strcmp(local.file_name(), "ss") == 0) above (and lines 72,73,79,80...) and for assert(strstr(local.function_name(), "main") != nullptr) here. |
I mentioned on Chat, but I see I didn't mention here: I'm not sure there's much point in committing this to libc++ until https://github.com/llvm/llvm-project/issues/48230 has been fixed in Clang, so that it can be properly used.
Given https://github.com/llvm/llvm-project/issues/48230 is closed, maybe we could move forward on this direction.
+1 for what it's worth the libc++ pre-commit CI now uses Clang-16. So if the issues are fixed in Clang-16 it might be worth to rebase the patch.
At this point, std::source_location::current() does still give the "wrong" result when used as a default argument.
After the discussion in https://reviews.llvm.org/D129488#3762490 about the unfortunate interaction between the specified behavior of source_location and consteval, the issue was brought to WG21 for comment, and is still under discussion there. I thought a possible outcome may be to switch current() from being consteval to instead being constexpr, but perhaps the consteval semantics will be changed, instead.
Naive question, but would everything work properly if libc++ used constexpr instead? As-in, would this patch work if you only changed that consteval to constexpr?
If so, I think it would be reasonable to do it. Concretely, we'll probably have an answer to this issue by the end of November in Kona, so we'll be able to fix it by the time we release LLVM 16. Also, constexpr is strictly more restrictive than consteval, so we could even ship it that way if it came to that. It would be subtly non-conforming, but at least it would give the right answer and users could start relying on the functionality, which is quite awaited.
Now that D136554 has re-landed, it seems that we're now actually good to go here (yay!)
PTAL at latest version.
LGTM % nits with green CI assuming you didn't change much about the implementation. I only looked through it quickly. There might be some tooling failing since we've added quite a bit in the last few months. Although I didn't notice while looking through the patch.
libcxx/include/source_location | ||
---|---|---|
39 | We switched to using this style a few months ago. | |
libcxx/test/std/language.support/support.srcloc/general.pass.cpp | ||
11–12 | We only support these compilers. |
Could you also add the paper to libcxx/docs/ReleaseNotes.rst in the Implemented Papers section?
The CI has some failures, but they all look unrelated. You don't have to run the CI again for the release note.
[ 96%] Generating ScudoUnitTest-i386-Test /b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/lib/gwp_asan/tests/recoverable.cpp:31:1: error: unused function 'DeallocateMemory2' [-Werror,-Wunused-function] DeallocateMemory2(gwp_asan::GuardedPoolAllocator &GPA, void *Ptr) { ^ 1 error generated.
That seems unrelated to this change.
Please update the source_location status in docs/Cxx2aStatusPaperStatus.csv. Look like this implements both both P1208 and LWG-3396.