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

            Bug ID: 66583
           Summary: incorrect implicitly-defined move constructor for
                    class with anonymous union and NSDMI
           Product: gcc
           Version: 5.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jens.maurer at gmx dot net
  Target Milestone: ---

The following code wrongly prints 0 instead of the correct 1:

$ g++ -std=c++11 union.cc 
$ ./a.out 
0

(reproducible with both 4.9.2 and 5.1.0)


#include <algorithm>
#include <iostream>

struct A {
  A() { };
  A(const A&) { }
};

struct B {
  union {
    int m_1 = 0;
    int m_2;
  };
  A dummy;
};

int main()
{
  B b;
  b.m_1 = 1;
  B c(std::move(b));
  std::cout << c.m_1 << std::endl;
}


The assembly code for B::B(B&&) when compiling unoptimized has this (x86-64):

        movl    (%rdx), %edx
        movl    %edx, (%rax)

Until here, we correctly copy the object representation of the anonymous union
(12.8p16).

        movq    -8(%rbp), %rax
        movl    $0, (%rax)

And then we seem to evaluate the non-static data member initializer for m_1,
which is (obviously) wrong.

Reply via email to