[BUG] `@copyable` type with `this` member isn't `std::copyable`
Title: @copyable with this member isn't std::copyable.
Description:
@copyable is documented as
https://github.com/hsutter/cppfront/blob/083c8a0d48df3d3d0d768b9a8b7ab2d26b98b515/source/reflect.h2#L704
But it's implemented as https://github.com/hsutter/cppfront/blob/083c8a0d48df3d3d0d768b9a8b7ab2d26b98b515/source/reflect.h2#L723
So when t has a this member,
only a copy constructor is generated.
Minimal reproducer (https://cpp2.godbolt.org/z/xnoEzc6GE):
sf_vertices: @basic_value type = { }
my_vertices: @basic_value type = {
this: sf_vertices = ();
operator=: (out this, size: i32) = _ = size;
}
tiles: type = {
public vertices: my_vertices;
operator=: (out this, size: i32) = vertices = size;
private operator=: (inout this, _: i32) = vertices = my_vertices(0);
}
main: () = { }
Commands:
cppfront main.cpp2
clang++18 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -Werror=unused-result -I . main.cpp
Expected result: An ill-formed program, or my_vertices to model std::copyable.
Actual result and error:
Cpp2 lowered to Cpp1:
//=== Cpp2 type declarations ====================================================
#include "cpp2util.h"
class sf_vertices;
class my_vertices;
class tiles;
//=== Cpp2 type definitions and function declarations ===========================
class sf_vertices {
public: sf_vertices([[maybe_unused]] sf_vertices const& that);
public: auto operator=([[maybe_unused]] sf_vertices const& that) -> sf_vertices& ;
public: sf_vertices([[maybe_unused]] sf_vertices&& that) noexcept;
public: auto operator=([[maybe_unused]] sf_vertices&& that) noexcept -> sf_vertices& ;
public: explicit sf_vertices();
};
class my_vertices: public sf_vertices {
public: explicit my_vertices(cpp2::in<cpp2::i32> size);
public: my_vertices(my_vertices const& that);
public: explicit my_vertices();
};
class tiles {
public: my_vertices vertices;
public: explicit tiles(cpp2::in<cpp2::i32> size);
private: auto operator=([[maybe_unused]] cpp2::in<cpp2::i32> param2) -> tiles& ;
public: tiles(tiles const&) = delete; /* No 'that' constructor, suppress copy */
public: auto operator=(tiles const&) -> void = delete;
};
auto main() -> int;
//=== Cpp2 function definitions =================================================
sf_vertices::sf_vertices([[maybe_unused]] sf_vertices const& that){}
auto sf_vertices::operator=([[maybe_unused]] sf_vertices const& that) -> sf_vertices& {
return *this;}
sf_vertices::sf_vertices([[maybe_unused]] sf_vertices&& that) noexcept{}
auto sf_vertices::operator=([[maybe_unused]] sf_vertices&& that) noexcept -> sf_vertices& {
return *this;}
sf_vertices::sf_vertices(){}
my_vertices::my_vertices(cpp2::in<cpp2::i32> size)
: sf_vertices{ }
{ static_cast<void>(size); }
my_vertices::my_vertices(my_vertices const& that)
: sf_vertices{ static_cast<sf_vertices const&>(that) }{}
my_vertices::my_vertices()
: sf_vertices{ }{}
tiles::tiles(cpp2::in<cpp2::i32> size)
: vertices{ size }
{ }
auto tiles::operator=([[maybe_unused]] cpp2::in<cpp2::i32> param2) -> tiles& {
vertices = my_vertices(0);
return *this;
}
auto main() -> int{}
main.cpp2:24:9: warning: definition of implicit copy assignment operator for 'my_vertices' is deprecated because it has a user-provided copy constructor [-Wdeprecated-copy-with-user-provided-copy]
24 | public: my_vertices(my_vertices const& that);
| ^
main.cpp2:10:54: note: in implicit copy assignment operator for 'my_vertices' first required here
10 | vertices = my_vertices(0);
| ^
1 warning generated.
See also:
- First discovered at https://github.com/hsutter/cppfront/issues/453#issuecomment-1690731171.
The same is true for the types in reflect.h2.
Those use @polymorphic_base @copyable.
They have a copy constructor, but not copy assignment or move operations.
For compiler_services in particular, which has no this member,
I suspect this is caused by the virtual destructor.