]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: allow array mem-init with -fpermissive [PR116634]
authorJason Merrill <jason@redhat.com>
Mon, 4 Nov 2024 22:48:46 +0000 (17:48 -0500)
committerJason Merrill <jason@redhat.com>
Tue, 5 Nov 2024 17:31:19 +0000 (12:31 -0500)
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)

gcc/cp/init.cc
gcc/testsuite/g++.dg/diagnostic/aggr-init1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/init/array62.C
gcc/testsuite/g++.dg/init/array63.C
gcc/testsuite/g++.dg/init/array64.C

index c5ba82c86648a5d63520872487984f6c58c696db..5a994378451b09ff00d6f8a5924944ea0974bce2 100644 (file)
@@ -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 (file)
index 0000000..b4b2d9e
--- /dev/null
@@ -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");
+}
index 2a786a36e4e8cd3e77b8e1a01bb988f8fc78deb2..6d3935d7a668d62c5693e078f662a6fb2c68b79d 100644 (file)
@@ -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 {
index 57e9805616804e4838acdfb11d022a8a6825018e..96bc9a64b26cf38c3f963fce8e53e0e4c5cc8653 100644 (file)
@@ -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};
index e0afdfab39a59678fa63bd9dd180ac382f0c2d6a..bbdd70c6df8c59d7876fe27d629fb9406a35d8e6 100644 (file)
@@ -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_;
 };