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] emitted initialisation of base class in member initialiser list of derived copy constructor does not compile #402

Closed
cpp-niel opened this issue May 1, 2023 · 2 comments · Fixed by #504
Labels
bug Something isn't working

Comments

@cpp-niel
Copy link

cpp-niel commented May 1, 2023

Describe the bug
If, within a class hierarchy, a derived type has an operator=: (out this, that), then the lowered cpp1 code will attempt to initialise the base class using that.Base as if Base were a member.

To Reproduce
Steps to reproduce the behavior:

  1. Sample code - distilled down to minimal essentials please
    The following cpp2 code:
Base : type = {
    operator=: (out this, that) = {}
}

Derived : type = {
    this: Base = ();
    operator=: (out this, that) = {}
}

will produce the following function definition for the copy constructor of Derived in cpp1:

    Derived::Derived(Derived const& that)
                                   : Base{ that.Base }
    {}

This will not compile.
2. Command lines including which C++ compiler you are using
cppfront is compiled with gcc12 and executed using

cppfront -p my_file.cpp2 -o stdout

The emitted cpp1 is also being compiled with gcc12.

  1. Expected result - what you expected to happen
    I would expect the copy constructor to be emitted as
    Derived::Derived(Derived const& that)
                                   : Base{ that }
    {}

and that the emitted code would compile

  1. Actual result/error5.
    The emitted code refers to the base class as that.Base and does not compile with the following error on gcc:
<source>:35:49: error: invalid use of 'Base::Base'
   35 |                                    : Base{ that.Base }
      |                                                 ^~~~
<source>:35:54: error: no matching function for call to 'Base::Base(<brace-enclosed initializer list>)'
   35 |                                    : Base{ that.Base }
      |      
@cpp-niel cpp-niel added the bug Something isn't working label May 1, 2023
@JohelEGP
Copy link
Contributor

JohelEGP commented May 1, 2023

5. Expected result - what you expected to happen
I would expect the copy constructor to be emitted as

    Derived::Derived(Derived const& that)
                                   : Base{ that }
    {}

and that the emitted code would compile

I think the access should be explicit
to prevent a templated constructor from being chosen over the copy constructor,
i.e., : Base{ static_cast<Base const&>(that) } rather than : Base{ that }.

JohelEGP referenced this issue May 8, 2023
And fix a bug this exposed - generated `operator=` memberwise emitted wrong syntax for a base type... previous test cases did not have copyable base types, but `cpp2::meta` embraces copyable base types as a design choice which is find because they aren't polymorphic in the usual inheritance sense
@JohelEGP
Copy link
Contributor

JohelEGP commented May 31, 2023

Fixed by 59fc520,
but not the way I suggested: https://cpp2.godbolt.org/z/Pboceoorz.
A templated constructor is chosen over a special member function.

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

Successfully merging a pull request may close this issue.

2 participants