https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90383

            Bug ID: 90383
           Summary: [9 Regression] GCC generates invalid constexpr
                    copy/move assignment operators for types with trailing
                    padding. (Again)
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: eric at efcs dot ca
  Target Milestone: ---

When a type has trailing padding GCC generates an invalid copy-assignment
operator for that type. (Similar to gcc.gnu.org/PR77945)

This time the copy assignment operator calls the default constructor, and does
not copy assign the value.

If the default constructor is deleted, GCC rejects-valid and the code fails to
compile. If the default constructor is available, GCC miscompiles the program.

This is a regression from the GCC 8.


Godbolt examples:
  * rejects-valid: https://godbolt.org/z/FGIyiM
  * miscompile: https://godbolt.org/z/7gL7iy

Reproducer:

// g++ -std=c++1z
struct alignas(8) data {
  constexpr data(bool) : value(true) {}

  // shouldn't be called. change to 'default' to see miscompile.
  data() = delete;

  bool value;
  // ... implicit padding ...
};

struct wrap { data member; };

constexpr bool always_true() {
    wrap w{data(true)};
    w.member = data(true);
    return w.member.value; // should always return true
}

bool test() {
    // emits-error {{use of deleted function 'data::data()'}}
    // emits-note {{in 'constexpr' expansion of 'always_true()' }}
    return always_true();

    // returns 0 when miscompiled.
}

Reply via email to