From 25ea3793defcdd0bd47aeb977a43dd0ebc4de6ae Mon Sep 17 00:00:00 2001 From: CLIF Team Date: Thu, 16 May 2024 08:00:56 -0700 Subject: [PATCH] Add support for polymorphic types that use destroying delete instead of a virtual destructor. The change makes types with an `operator delete(..., std::destroying_delete_t)` to be handled the same way abstract classes are handled (ie with unique_ptr), allowing subclasses to be constructed during marshalling. Tested: Presubmit TGP with custom binary (rerun) OCL:633257130:BASE:634387810:1715870484576:3c4e7d32 PiperOrigin-RevId: 634394623 --- clif/backend/matcher.cc | 4 +++- clif/backend/matcher_test.cc | 11 +++++++++++ clif/backend/test.h | 13 +++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/clif/backend/matcher.cc b/clif/backend/matcher.cc index a0300fe3..ff826c42 100644 --- a/clif/backend/matcher.cc +++ b/clif/backend/matcher.cc @@ -1372,7 +1372,9 @@ void ClifMatcher::SetTypePropertiesHelper(clang::CXXRecordDecl* clang_decl, !ast_->DestructorIsAccessible(clang_decl)) { clif_decl->set_cpp_movable(false); } - if (clang_decl->isAbstract()) { + if (clang_decl->isAbstract() || + std::any_of(clang_decl->method_begin(), clang_decl->method_end(), + [](auto* md) { return md->isDestroyingOperatorDelete(); })) { clif_decl->set_cpp_abstract(true); } SetUniqueClassProperties(clang_decl, clif_decl); diff --git a/clif/backend/matcher_test.cc b/clif/backend/matcher_test.cc index 7ef94fee..611d2ee1 100644 --- a/clif/backend/matcher_test.cc +++ b/clif/backend/matcher_test.cc @@ -940,6 +940,11 @@ TEST_F(ClifMatcherTest, TestMatchSetTypeProperties) { "name { cpp_name: 'AbstractClass' } " "}", &decl); EXPECT_TRUE(decl.class_().cpp_abstract()); + TestMatch( + "decltype: CLASS class_ { " + "name { cpp_name: 'DestroyingDeleteClass' } " + "}", &decl); + EXPECT_TRUE(decl.class_().cpp_abstract()); TestMatch( "decltype: CLASS class_ { " "name { cpp_name: 'PrivateDestructorClass' } " @@ -972,6 +977,12 @@ TEST_F(ClifMatcherTest, TestCppAbstract) { "params { type { lang_type: 'AbstractClass' " " cpp_type: 'AbstractClass' } } }", &decl); EXPECT_TRUE(decl.func().params(0).type().cpp_abstract()); + + TestMatch("decltype: FUNC func { " + "name { cpp_name: 'FuncAbstractParam' } " + "params { type { lang_type: 'DestroyingDeleteClass' " + " cpp_type: 'DestroyingDeleteClass' } } }", &decl); + EXPECT_TRUE(decl.func().params(0).type().cpp_abstract()); } TEST_F(ClifMatcherTest, TestMatchAndSetTemplateTypes) { diff --git a/clif/backend/test.h b/clif/backend/test.h index fb5b7928..d6014452 100644 --- a/clif/backend/test.h +++ b/clif/backend/test.h @@ -20,6 +20,14 @@ #define CLIF_BACKEND_TEST_H_ #include + +namespace std { +struct destroying_delete_t { + explicit destroying_delete_t() = default; +}; +inline constexpr destroying_delete_t destroying_delete{}; +} // namespace std + // These are all declared in the same file to make lookup inside the // TU complicated enough to be convincing. @@ -105,6 +113,10 @@ class AbstractClass { virtual void Func() = 0; }; +class DestroyingDeleteClass { + public: + void operator delete(DestroyingDeleteClass*, std::destroying_delete_t); +}; class DerivedClass : public Class { public: @@ -317,6 +329,7 @@ class ClassOverridesPureVirtual: public ClassPureVirtual { void SomeFunctionNotPureVirtual(); void FuncAbstractParam(const ClassPureVirtual* x); void FuncAbstractParam(const AbstractClass& x); +void FuncAbstractParam(const DestroyingDeleteClass& x); void FuncForwardDeclared(const Globally::Qualified::ForwardDecl* x); // tests to be sure we don't match a return in const param.