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

            Bug ID: 128653
           Summary: Constant-initialized array of NSDMI class loses
                    trailing elements after element assignment in
                    constexpr function
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: barry.revzin at gmail dot com
  Target Milestone: ---

My colleague (Tom Carotti) ran into this miscompilation:

using size_t = decltype(sizeof(0));

template <class T, size_t N>
struct array {
    T elems[N];
};

struct Storage {
    char value = 'x';
};

auto values = [] {
    array<Storage, 10> result{};
    result.elems[2].value = 0;
    return result;
}();

This emits:

"values":
        .byte   120
        .byte   120
        .byte   0
        .zero   7

Writing to elems[2] corrupts every trailing element! Note that writing to
elems[0] or elems[1] works fine, only that element is zeroed, it's only
starting at 2 that we see this behavior. 

Another example:

struct S { char c = 1; };                                                       
struct A { S e[8]; };                                                           

constexpr A f(int i) {                                                          
    A a{};                                                                      
    a.e[i].c = 0;                                                               
    return a;                                                                   
}                                                                               

A v = f(5);  // expect 1 1 1 1 1 0 1 1                                          
A w = f(3);  // expect 1 1 1 0 1 1 1 1

On gcc, v is [1, 1, 1, 0, 0, 0, 1, 1] instead. However, if you comment out the
declaration of w, then v actually is correctly [1, 1, 1, 1, 1, 0, 1, 1]! We're
retroactively breaking a constant initialization?!

Moreover, this seems to fail on every version of gcc since like 9.1.0. It works
correctly on all of the 8.x's I tried.

Reply via email to