Try to use the existing cleanup machinery to implement calling destructors.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
clang/lib/AST/Interp/ByteCodeExprGen.cpp | ||
---|---|---|
29 | I changed VariableScope to do the destructor handling, bu that's not needed for "temporaries in toplevel variable desclarations" (also, but unrelated, inherting from something called "local scope" but then explaining in a comment that it's only used for toplevel declarations is kinda weird). |
Looks like I have to actually go up the class chain and emit all destructors manually.
clang/lib/AST/Interp/ByteCodeExprGen.cpp | ||
---|---|---|
1860–1862 | As a FIXME: you should also handle virtual destructors at some point, whenever you get around to handling virtual functions in general. | |
1875–1876 | isTrivial() only works once the class has been fully built up by Sema IIRC; we should have a test case for that situation. | |
1877 | This looks like it will destroy the array elements in order instead of in reverse order -- need test coverage for that. See https://eel.is/c++draft/class.dtor#13.sentence-5 | |
1894 | Won't this also destroy static data members? (Needs a test case for that.) Also, what if the record is a union and not a structure? We only want to destroy the active member in that case, not all of the variant members, right? (Also needs a test case.) | |
1918–1923 | I don't think we handle virtual functions yet so I doubt we handle virtual bases, but that's something that might need a FIXME comment. | |
clang/lib/AST/Interp/ByteCodeExprGen.h | ||
327 | No need to add the virtual here as the override already signals that (can't override a non-virtual function). |
clang/lib/AST/Interp/ByteCodeExprGen.cpp | ||
---|---|---|
1875–1876 | Are you saying that isTrivial() cannot be used like this, or just that it can, but needs a test case to ensure that this is true? Also, how would such a test case look like? | |
1877 | Right, that makes a lot of sense, good catch. | |
1894 | I saw // A union destructor does not implicitly destroy its members. if (RD->isUnion()) return true; in ExprConstant.cpp, but since we don't handle unions at all in the new interpreter right now, I didn't add anything for them. I added a comment. |
clang/lib/AST/Interp/ByteCodeExprGen.cpp | ||
---|---|---|
1875–1876 | Sema::DeclareImplicitDestructor() decides whether the destructor is trivial or not, and that is based on information that the class collects as the class is being declared. While the class is being parsed, the DeclarationData for the class is updated as we go and we use that to decide if we need the destructor, whether it's trivial, etc. So it's possible for us to have not seen a part of the class yet that would cause the special member function to be (non)trivial and so asking the method "are you trivial" may give a different answer depending on when the question is asked. In terms of a test case, I think it would be trying to hit one of these cases http://eel.is/c++draft/class.mem#class.dtor-8 by using a constexpr function that needs to be evaluated before we get to something that causes the dtor to no longer be trivial. |
clang/lib/AST/Interp/ByteCodeExprGen.cpp | ||
---|---|---|
1875–1876 | Hm, I can't come up with a reproducer for this. The class of a member variable must be fully defined when the member is declared, so I can't forward-declare it and then introduce a non-trivial destructor later. And as soon as I add a destructor declaration (and try to define i later), the destructor is automatically not trivial anymore. |
LGTM assuming no surprises with the new test request.
clang/lib/AST/Interp/ByteCodeExprGen.cpp | ||
---|---|---|
1875–1876 | Yeah, I'm struggling to make a test case as well, so let's move on. | |
clang/test/AST/Interp/cxx20.cpp | ||
493 | Another test case that I think would be interesting is with a static member that is not constexpr (to show it doesn't cause problems) and an out-of-line destructor just because it's a bit of an oddity: https://godbolt.org/z/YqrPMEEr4 |
No need to add the virtual here as the override already signals that (can't override a non-virtual function).