https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108683

            Bug ID: 108683
           Summary: Move Occurs when initializing an aggregate base
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: davidledger at live dot com.au
  Target Milestone: ---

```CPP
struct Bar
{
    Bar() = delete;
    Bar(Bar const &) = delete;
    Bar& operator=(Bar const&) = delete;
    Bar(Bar&&) = delete;
    Bar& operator=(Bar&&) = delete;

    explicit Bar(int value) : m_value(value) {}
    int m_value;
};

namespace A
{
    struct Foo : Bar{}; // this is the only difference.

    Bar MakeBar()
    {
        return Bar(10);
    }
}

namespace B
{
    struct Foo
    {
        Bar bar; // this is the only difference.
    };

    Bar MakeBar()
    {
        return Bar(10);
    }
}

int main()
{
    A::Foo foo{ A::MakeBar() };
    B::Foo bar{ B::MakeBar() };
}
```

The above example, while failing similarly in clang and GCC. Compiles without
issue on MSVC. 

As of C++17:
> An aggregate class or array may include non-aggregate public bases (since 
> C++17), members, or elements, which are initialized as described above (e.g. 
> copy-initialization from the corresponding initializer clause).
cppreference.

So we have an aggregate here. When using GCC, the following error is presented:
```
<source>: In function 'int main()':
<source>:38:30: error: use of deleted function 'Bar::Bar(Bar&&)'
   38 |     A::Foo foo{ A::MakeBar() };
      |                              ^
<source>:6:5: note: declared here
    6 |     Bar(Bar&&) = delete;
      |     ^~~
Compiler returned: 1
```
I believe this should compile without requiring a move constructor of the base
type.

Reply via email to