[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