Skip to content
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

[BUG] @copyable type with this member isn't std::copyable #779

Open
JohelEGP opened this issue Oct 25, 2023 · 1 comment
Open

[BUG] @copyable type with this member isn't std::copyable #779

JohelEGP opened this issue Oct 25, 2023 · 1 comment
Labels
bug Something isn't working

Comments

@JohelEGP
Copy link
Contributor

Title: @copyable with this member isn't std::copyable.

Description:

@copyable is documented as

// A type with (copy and move) x (construction and assignment)

But it's implemented as

t.add_member( "operator=: (out this, that) = { }");

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{}
Output:
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:

@JohelEGP JohelEGP added the bug Something isn't working label Oct 25, 2023
@JohelEGP JohelEGP changed the title [BUG] @copyable with this member isn't std::copyable [BUG] @copyable type with this member isn't std::copyable Oct 25, 2023
@JohelEGP
Copy link
Contributor Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant