diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 5f7fc6f8f0c1b787ee23f6630f2e2bbfd5802753..5e0d3399172202b5d68386b5132bd08ce0e4bebd 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -3081,7 +3081,13 @@ reduced_constant_expression_p (tree t) element. */ if (!reduced_constant_expression_p (e.value)) return false; - /* Empty class field may or may not have an initializer. */ + /* We want to remove initializers for empty fields in a struct to + avoid confusing output_constructor. */ + if (is_empty_field (e.index) + && TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE) + return false; + /* Check for non-empty fields between initialized fields when + CONSTRUCTOR_NO_CLEARING. */ for (; field && e.index != field; field = next_subobject_field (DECL_CHAIN (field))) if (!is_really_empty_class (TREE_TYPE (field), diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda27.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda27.C new file mode 100644 index 0000000000000000000000000000000000000000..24e2e9b6c989e50325e5d782f0231b587a3bbe46 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda27.C @@ -0,0 +1,26 @@ +// PR c++/106369 +// { dg-do compile { target c++17 } } + +struct A { + int a[256]; + constexpr int &operator[] (int n) noexcept { return a[n]; } + constexpr const int &operator[] (int n) const noexcept { return a[n]; } +}; +struct B {}; +template <typename T> +struct C { + constexpr T &foo (const char x) noexcept { c = T::d[x]; return static_cast<T &>(*this); } + int c; +}; +struct D : public C<D>, public B +{ + D () noexcept = default; + static constexpr char e[9] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' }; + static constexpr A d = [] () constexpr { + A f {}; + for (int i = 0; i < 9; ++i) + f[e[i]] = 1; + return f; + } (); +}; +constexpr auto g = D{}.foo ('E');