https://gcc.gnu.org/g:ce25ca4da198ebc269d41ee6a9ac880ae8f67ad6
commit r14-10887-gce25ca4da198ebc269d41ee6a9ac880ae8f67ad6 Author: Jason Merrill <ja...@redhat.com> Date: Mon Nov 4 17:48:46 2024 -0500 c++: allow array mem-init with -fpermissive [PR116634] We've accidentally accepted this forever (at least as far back as 4.7), but it's always been ill-formed; this was PR59465. And we didn't accept it for scalar types. But rather than switch to a hard error for this code, let's give a permerror so affected code can continue to work with -fpermissive. PR c++/116634 gcc/cp/ChangeLog: * init.cc (can_init_array_with_p): Allow PR59465 case with permerror. gcc/testsuite/ChangeLog: * g++.dg/diagnostic/aggr-init1.C: Expect warning with -fpermissive. * g++.dg/init/array62.C: Adjust diagnostic. * g++.dg/init/array63.C: Adjust diagnostic. * g++.dg/init/array64.C: Adjust diagnostic. (cherry picked from commit 3545aab00152ed3db1d7ce6ca4e1671dde276980) Diff: --- gcc/cp/init.cc | 4 ++- gcc/testsuite/g++.dg/diagnostic/aggr-init1.C | 37 ++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/init/array62.C | 2 +- gcc/testsuite/g++.dg/init/array63.C | 2 +- gcc/testsuite/g++.dg/init/array64.C | 2 +- 5 files changed, 43 insertions(+), 4 deletions(-) diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index c5ba82c86648..5a994378451b 100644 --- a/gcc/cp/init.cc +++ b/gcc/cp/init.cc @@ -962,7 +962,9 @@ can_init_array_with_p (tree type, tree init) return true; } - return false; + permerror (input_location, "array must be initialized " + "with a brace-enclosed initializer"); + return true; } /* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of diff --git a/gcc/testsuite/g++.dg/diagnostic/aggr-init1.C b/gcc/testsuite/g++.dg/diagnostic/aggr-init1.C new file mode 100644 index 000000000000..b4b2d9e69e1d --- /dev/null +++ b/gcc/testsuite/g++.dg/diagnostic/aggr-init1.C @@ -0,0 +1,37 @@ +// PR c++/116634 +// { dg-do compile { target c++11 } } +// { dg-additional-options -fpermissive } + +namespace std { + using size_t = decltype(sizeof(42)); +} + +class ConstString final { +public: + constexpr ConstString() noexcept: buf(), len(0) {} + template<int N> + constexpr ConstString(const char (&a)[N]): buf(a), len(N - 1) {} + constexpr ConstString(const ConstString &c1): buf(c1.buf), len(static_cast<int>(c1.len)) {} + +private: + const char* buf; + int len; +}; + +template<int N> +struct Any final { + constexpr + Any(ConstString (&&_vec)[N]) noexcept: vec(_vec){} // { dg-warning "array" } + + ConstString vec[N]; +}; + +template<int... N1> +constexpr static +auto Any_of(const char (&...c1)[N1]) -> Any<static_cast<int>(sizeof...(N1))> { + return {{ConstString(c1)...}}; +} + +int main() { + constexpr static const auto aa1 = Any_of("abcd", "def"); +} diff --git a/gcc/testsuite/g++.dg/init/array62.C b/gcc/testsuite/g++.dg/init/array62.C index 2a786a36e4e8..6d3935d7a668 100644 --- a/gcc/testsuite/g++.dg/init/array62.C +++ b/gcc/testsuite/g++.dg/init/array62.C @@ -4,7 +4,7 @@ struct string {} a[1]; struct pair { string s[1]; - pair() : s(a) {} // { dg-error "invalid initializer for array member" } + pair() : s(a) {} // { dg-error "array must be initialized" } }; struct S { diff --git a/gcc/testsuite/g++.dg/init/array63.C b/gcc/testsuite/g++.dg/init/array63.C index 57e980561680..96bc9a64b26c 100644 --- a/gcc/testsuite/g++.dg/init/array63.C +++ b/gcc/testsuite/g++.dg/init/array63.C @@ -7,7 +7,7 @@ struct I { struct O { I a[2]; static I const data[2]; - O() : a(data){} // { dg-error "invalid initializer for array member" } + O() : a(data){} // { dg-error "array must be initialized" } }; I const O::data[2] = {true, false}; diff --git a/gcc/testsuite/g++.dg/init/array64.C b/gcc/testsuite/g++.dg/init/array64.C index e0afdfab39a5..bbdd70c6df8c 100644 --- a/gcc/testsuite/g++.dg/init/array64.C +++ b/gcc/testsuite/g++.dg/init/array64.C @@ -16,7 +16,7 @@ typedef UserType Array[my_size]; class Foo { public: - Foo(Array& m) : m_(m) {}; // { dg-error "invalid initializer for array member" } + Foo(Array& m) : m_(m) {}; // { dg-error "array must be initialized" } private: Array m_; };