https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82899
Bug ID: 82899
Summary: *this in constructors could not alias with reference
input parameters of the same type
Product: gcc
Version: 8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: antoshkka at gmail dot com
Target Milestone: ---
Following code
struct test {
char data[2] = {1, 2};
test(const test& v);
~test(){} // non trivial destructor!
};
test::test(const test& v)
: data{ v.data[0], v.data[0] }
{}
Produces the following assembly:
test::test(test const&):
movzx eax, BYTE PTR [rsi]
mov BYTE PTR [rdi], al
movzx eax, BYTE PTR [rsi] <=== This is not required
mov BYTE PTR [rdi+1], al
ret
`*this` could not alias with `v` because `v` is already constructed while *this
is still being constructed. Any attempt to make `*this` alias `v` is a UB:
#1
test t; // let's assume that `test` is default constructible
new (&t) test(t); // UB: destructor was not called
#2
std::aligned_storage_t<test> t;
new (&t) test(reinterpret_cast<test&>(t)); // UB: test was not constructed on t
#3 (doubtful)
test t; // let's assume that `test` has trivial destructor
// t.~test(); // users may skip this call
new (&t) test(t); // extremely wired
Please, either assume that *this never alias input parameter of the same type
OR
assume that *this never alias input parameter of the same type if the
destructor is not trivial.
This aliasing issue affects performance of all the copy and move constructors.