-
Notifications
You must be signed in to change notification settings - Fork 261
[Suggestion] Update cppfront to enable C++23 tests for modern Clang versions #1083
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
Conversation
I hadn't heard about that. Hmm... that seems like it would break a lot of code. I just checked with gcc trunk and Clang trunk and a Except only if you you actually write a custom dtor for a type like |
I think it's a Clang/LLVM bug introduced (or exposed) in Clang 15. First, with the destructor code enabled in Herb's example, it compiles correctly in Clang 14, GCC latest and MSVC latest. Second, although I couldn't find an LLVM bug with this exact code example, there are a couple open LLVM bugs which appear to describe the same problem:
In particular, note Richard Smith's comment in the first issue above:
I believe he's saying "so gets instantiated [by Clang] more eagerly", rather than saying that the C++ standard requires that to happen. A statement in the second issue seems to confirm this:
|
Thanks both for the research! Adding emphasis, Richard is quoted as saying:
That seems to confirm the fix/workaround is to write the dtors out-of-line for any type |
Great to hear it is just a bug in Clang. I am currently working with C++20 and 23 is still a bit of uncharted ground for me. Given that we are talking about a bug in a compiler any change in the code due to that would sound like a pessimisation. I was looking for a temporary solution that would be "minimally invasive" (a buzz term from the medical industry) and trivial to remove in the long term, hence my proposition. It is, of course, also possible just to wait for a fixed version of Clang to become available on GitHub runners. Given that the trunk version is already OK this might be a relatively near ETA. |
It's not clear to me from the description so far whether it's a compiler bug or a change in standard behavior. But making such destructors out-of-line shouldn't a big change... moving function to later in the file is something we have to do already for a bunch of functions for forward-decl reasons(*) especially in (*) and wouldn't once the code is migrated to to Cpp2, because all functions are forward-declared and all the definitions are out-of-line later in the file so the problem doesn't arise |
Out of curiosity I've just tried this. EDIT: Fixed the link. |
Right, I think that's because the use of I think it's the same as this explicitly written destructor: https://godbolt.org/z/YjMf5cnKr |
I asked about this on Discord with a slightly smaller example: struct B;
struct A {
~A() { std::cout << "~A\n"; };
std::unique_ptr<B> pb;
};
struct B {
~B() { std::cout << "~B\n"; };
};
int main() {
A a;
a.pb = std::make_unique<B>();
} and Brian Bi (with permission to quote him) said:
|
If fact cppreference.com states that:
which seems quite obvious when you read it. Nevertheless, it is interesting that all compilers seem to have had a consensus since C++11 to accept ill formed code examples we are discussing here deferring the definition o default destructors. It seems like a natural way to implement things. Anyway @hsutter what is you take on this PR? How about I try to implement the out-of-line dtors? |
Thanks for offering! Yes, I think for this PR the best would be to start fresh and have the only diffs be to move "just enough" dtors to be out-of-line to satisfy Clang. That should means diffs only in I notice this PR also had other changes to YML and regression test results. Those could be a second separate PR, once we merge the PR that focuses on unblocking the Clang builds? |
I will split that into two PRs, then. I am closing this one. |
In C++23, the default deleter used by
std::unique_ptr
has becomeconstexpr
, which requires the destructor of the pointed-to type to be available at compile time. As a result, forward-declared types cannot be used in a defaultstd::unique_ptr
. For this reason it is impossible to compile cppfront using Clang 18 and--std=c++2b
. The compilation fails with something like:(see e.g. here).
Probably the cleanest solution would be to rework the code of cppfront to remove the use of forward-declared types used in
std::unique_ptr
. However, doing this in a single shot would be quite cumbersome.A stepping stone could be to use
std::unique_ptr
with a custom deleter that works for forward-declared types if C++>=23 is requested. This would allow to update the code iteratively, while already enabling Clang 18 with C++23.In short, this PR addresses the issue by introducing
cpp2::impl::unique_ptr
andcpp2::impl::make_unique
and temporarily replacing the use of thestd
counterparts throughout the code by those:std::unique_ptr
andstd::make_unique
into thecpp2::impl
namespace as they work without problem.constexpr
)custom_delete
is defined,cpp::impl::unique_ptr
is an alias ofstd::unique_ptr<T, cpp2::impl::custom_delete<T>>;
andcpp2::impl::make_unique
usesstd::make_unique
but returnscpp::impl::unique_ptr
.In subsequent commits the GitHub regression test workflows are updated and tests files are updated accordingly. As a result, Clang 18 with C++23 (and
libc++-18-dev
) becomes the firsts non-MSVC compiler in the CI that succeeds to build and run all the regression tests (see here).So far all other non-MSVC compilers in the CI fail to compile at least one of the tests.
It is also quite likely that MSVC is able to compile cppfront with C++23 because the
constexpr
version ofstd::default_delete
is not yet implemented...The added value of the proposed solution is also the triviality of the steps necessary to revert the changes in cppfront when the code no longer has forward-declared types in
unique_ptr
s. Except for the single block of code added ininclude/cpp2util.h
all other changes in the code in the PR are find/replace.Note that the test file updates are added in the last commit. I suggest to review the main part of the changes through the first two commits: ffe7646 and 2a14b2e. It is possible to add comments there.