<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - Miscompile of defaulted union copy ctor"
   href="https://llvm.org/bugs/show_bug.cgi?id=23373">23373</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Miscompile of defaulted union copy ctor
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Windows NT
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>-New Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>dario.domizioli@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Contrived example:

// ---------------------------------------------------------------------------
int testflag = 0;

int main() {

    union U {
        int data;              // Some data member.
        U(U&) = default;       // Note the non-const &. It is allowed by the
                               // standard. A non-deleted, defaulted copy ctor
                               // should copy the data representation of the
                               // union.
        U(int u) { data = u; } // Constructor from int.
    } obj1(2), obj2(obj1);     // Obj2 must be initialized after obj1, so it
                               // should contain 2.

    if(obj2.data != 2) {       // This should be false (i.e. obj2.data == 2)!
        testflag++;            // This should never be executed, but it is!
    }
    return testflag;
}
// ---------------------------------------------------------------------------

Compile and link with just: clang -std=c++11 <file>
I am using the x86_64-unknown-linux triple.

Even when compiled at -O0, testflag is incremented and this code returns with
an exit code of 1.
I believe the implementation of the explicitly-defaulted, implicitly-defined,
non-const-& version of the copy ctor for union U is miscompiled.

I've looked at my copy of the C++11 standard (INCITS+ISO+IEC+14882-2012) and I
think the code is OK.

The copy ctor is allowed to have a non-const reference and it's still a copy
ctor (Clause 12.8 paragraph 2).
An explicitly defaulted copy ctor is implicitly defined in this case (Clause
12.8 paragraph 13).
An implicitly defined copy ctor for a union copies the object representation of
the union (Clause 12.8 paragraph 16) so it should copy the data.
The initialization of "obj2" must happen after "obj1" because of Clause 8,
paragraph 3 (and footnote 97 for clarification).

I have also noticed that the miscompile does not seem to happen when the
defaulted copy ctor is the "const&" variant.
    U(U const&) = default; // This would work fine.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>