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

            Bug ID: 115900
           Summary: [14 Regression] constexpr object modification during
                    construction gives "Modifying a const object is not
                    allowed in a constant expression"
           Product: gcc
           Version: 14.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: valentin at tolmer dot fr
  Target Milestone: ---

The smallest example I could make is:

```cpp
struct A {
    char data;
    constexpr explicit A() {
        data = 0;
    }
};

struct C {
  constexpr C(int) {}
  constexpr C() = default;
};

struct B : public C {
  A a;
  explicit constexpr B() : C(0) {}
};

struct D : public B {};

static constexpr A a;
static constexpr B b;
static constexpr D d;
```


Building `a` and `b` succeed, but `d` fails with:
```
$ g++ -std=c++20 <source>
<source>:22:20:   in 'constexpr' expansion of 'D()'
<source>:18:8:   in 'constexpr' expansion of '((D*)this)->D::B.B::B()'
<source>:15:31:   in 'constexpr' expansion of '((B*)this)->B::a.A::A()'
<source>:4:14: error: modifying a const object '((A*)this)->A::data' is not
allowed in a constant expression
    4 |         data = 0;
      |         ~~~~~^~~
<source>:22:20: note: originally declared 'const' here
   22 | static constexpr D d;
      |                    ^
```

This compiles fine with GCC 13.3.0, but fails with GCC 14.1.0 or trunk (on
godbolt as of this writing, g++
(Compiler-Explorer-Build-gcc-88ff0504ab3286df57e27514065494a30c365ec5-binutils-2.42)
15.0.0 20240712 (experimental) ).

https://godbolt.org/z/TvjM4qjb6

AFAIK, a constexpr object only becomes const after the construction ended (the
constructor returns). Moreover, there's no reason why B works but not D.
Interestingly, calling C's default constructor instead of the one that takes an
`int` (inside B) makes the code compile.

Reply via email to