[llvm-bugs] [Bug 46209] New: Clang incorrectly marks defaulted copy assignments as trivial

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Jun 4 13:55:41 PDT 2020


https://bugs.llvm.org/show_bug.cgi?id=46209

            Bug ID: 46209
           Summary: Clang incorrectly marks defaulted copy assignments as
                    trivial
           Product: clang
           Version: 9.0
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: -New Bugs
          Assignee: unassignedclangbugs at nondot.org
          Reporter: cfsteefel at gmail.com
                CC: htmldeveloper at gmail.com, llvm-bugs at lists.llvm.org,
                    neeilans at live.com, richard-llvm at metafoo.co.uk

Created attachment 23581
  --> https://bugs.llvm.org/attachment.cgi?id=23581&action=edit
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.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200604/198df9e4/attachment-0001.html>


More information about the llvm-bugs mailing list