https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102307
--- Comment #7 from jyhgekyfbkjsyebf at protonmail dot ch --- Note that: * based on repro: if I add constexpr to the first ctor and provide body, it will compile without error. Like this: constexpr Matrix(double const (&arr)[N][M]) {} * based on repro: if I comment out the second ctor declaration, compiler will produce an error (instead of a crash). Like this: // constexpr Matrix(std::array<std::array<double, M>, N> const &arr); * based on repro: if I add a data member, and * provide body to the first ctor, and * inside use std::copy to fill the member the compiler will crash. Like this: ``` #include <algorithm> #include <array> template <unsigned N, unsigned M> struct Matrix { std::array<double, N * M> mat; Matrix(double const (&arr)[N][M]) { std::copy(&arr[0][0], &arr[0][0] + N * M, std::begin(mat)); } constexpr Matrix(std::array<std::array<double, M>, N> const &arr); }; int main() { constexpr Matrix<2, 3> mat{{{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}}}; } ``` * based on last case: if I replace std::copy call with 2 for loops, and * add constexpr to first ctor, and * add -std=c++20 flag the code will compile. Like this: ``` constexpr Matrix(double const (&arr)[N][M]) { for (auto n{0U}; n < N; ++n) { for (auto m{0U}; m < M; ++m) mat[n * M + m] = arr[n][m]; } } ``` As you can see, the results due to slight changes are all over the place. I leave it up to you to interpret them. All of the above is reproducible on godbolt. I only used local gcc to generate backtrace, everything else was tinkered with there.