<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </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 - Clang incorrectly marks defaulted copy assignments as trivial"
   href="https://bugs.llvm.org/show_bug.cgi?id=46209">46209</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Clang incorrectly marks defaulted copy assignments as trivial
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>9.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

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

        <tr>
          <th>Severity</th>
          <td>enhancement
          </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>cfsteefel@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org, neeilans@live.com, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=23581" name="attach_23581" title="A potential patch, that seems to fix the miscompilation issue.">attachment 23581</a> <a href="attachment.cgi?id=23581&action=edit" title="A potential patch, that seems to fix the miscompilation issue.">[details]</a></span>
A potential patch, that seems to fix the miscompilation issue.

When compiling a type containing at least one field that is considered non
trivial, clang can incorrectly mark the type as trivially copy assignable when
the non trivial type contains both a valid non-trivial copy assignment
operator, qualified with & or &&, as well as a deleted copy assignment operator
marked with the other form of qualification. This can be discovered at compile
time by checking that std::is_trivially_copy_assignable< type >::value is true
in this case. It also causes incorrect generated code, as a trivial copy
(std::memmove) is performed on the type, leading to constructors not being
called for the non-trivial field.

A minimal reproduction is as follows:
#include <type_traits>

struct Foo {
    Foo & operator=(const Foo &) & {
        return *this;
    }
    Foo & operator=(const Foo &) && = delete;
};

struct Bar {
    Foo foo;
};

static_assert(!std::is_trivially_copy_assignable< Foo >::value, "");
static_assert(!std::is_trivially_copy_assignable< Bar >::value, ""); // fails

int main() { return 0; }

The same issue does not appear to exist for move assignment operators.

The bug itself seems to be caused since clang will resolve the initial copy
assignment operator, marking the type as non-trivial, then will process the
deleted copy assignment operator, and mark the type as trivial as well (leaving
the type/field marked as both).

I have attached a potential patch that seems to fix the issue, but my knowledge
of how to actually access the non-deleted copy assignment operator is limited,
so it involves brute force (the patch was applied to clang 9, to get the line
numbers). If desired, I can formalize the patch alongside a test case against
clang's master branch instead.</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>