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.

Reply via email to