Skip to content

[BUG] emitted initialisation of base class in member initialiser list of derived copy constructor does not compile #402

Closed

Description

@cpp-niel

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 }
      |      

Activity

  1. JohelEGP commented on May 1, 2023

    @JohelEGP
    Contributor

    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 }.

  2. JohelEGP commented on May 31, 2023

    @JohelEGP
    Contributor

    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions