aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2021-06-29 14:30:51 -0400
committerMarek Polacek <polacek@redhat.com>2021-06-30 12:11:17 -0400
commite66d0b7b87d105d24da8c4784a0b907fb6b2c095 (patch)
tree2f138c42691407b73a4c335bad2e43d13620c484
parenta075350ee7bffa6c90d9d233de78515f498b5149 (diff)
downloadgcc-e66d0b7b87d105d24da8c4784a0b907fb6b2c095.zip
gcc-e66d0b7b87d105d24da8c4784a0b907fb6b2c095.tar.gz
gcc-e66d0b7b87d105d24da8c4784a0b907fb6b2c095.tar.bz2
c++: DR2397 - auto specifier for * and & to arrays [PR100975]
This patch implements DR2397, which removes the restriction in [dcl.array]p4 that the array element type may not be a placeholder type. We don't need to worry about decltype(auto) here, so this allows code like int a[3]; auto (*p)[3] = &a; auto (&r)[3] = a; However, note that auto (&&r)[2] = { 1, 2 }; auto arr[2] = { 1, 2 }; still doesn't work (although one day it might) and neither does int arr[5]; auto x[5] = arr; given that auto deduction is performed in terms of function template argument deduction, so the array decays to *. PR c++/100975 DR 2397 gcc/cp/ChangeLog: * decl.c (create_array_type_for_decl): Allow array of auto. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/auto24.C: Remove dg-error. * g++.dg/cpp0x/auto3.C: Adjust dg-error. * g++.dg/cpp0x/auto42.C: Likewise. * g++.dg/cpp0x/initlist75.C: Likewise. * g++.dg/cpp0x/initlist80.C: Likewise. * g++.dg/diagnostic/auto1.C: Remove dg-error. * g++.dg/cpp23/auto-array.C: New test.
-rw-r--r--gcc/cp/decl.c11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/auto24.C3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/auto3.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/auto42.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist75.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist80.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp23/auto-array.C36
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/auto1.C3
8 files changed, 45 insertions, 18 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index fa6af6f..7672947 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -10969,17 +10969,6 @@ create_array_type_for_decl (tree name, tree type, tree size, location_t loc)
if (type == error_mark_node || size == error_mark_node)
return error_mark_node;
- /* 8.3.4/1: If the type of the identifier of D contains the auto
- type-specifier, the program is ill-formed. */
- if (type_uses_auto (type))
- {
- if (name)
- error_at (loc, "%qD declared as array of %qT", name, type);
- else
- error ("creating array of %qT", type);
- return error_mark_node;
- }
-
/* If there are some types which cannot be array elements,
issue an error-message and return. */
switch (TREE_CODE (type))
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto24.C b/gcc/testsuite/g++.dg/cpp0x/auto24.C
index 193f92e..ac1ba24 100644
--- a/gcc/testsuite/g++.dg/cpp0x/auto24.C
+++ b/gcc/testsuite/g++.dg/cpp0x/auto24.C
@@ -1,5 +1,6 @@
// PR c++/48599
// { dg-do compile { target c++11 } }
+// Allowed since DR2397.
int v[1];
-auto (*p)[1] = &v; // { dg-error "8:.p. declared as array of .auto" }
+auto (*p)[1] = &v;
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto3.C b/gcc/testsuite/g++.dg/cpp0x/auto3.C
index 2cd0520..7cde745 100644
--- a/gcc/testsuite/g++.dg/cpp0x/auto3.C
+++ b/gcc/testsuite/g++.dg/cpp0x/auto3.C
@@ -9,8 +9,8 @@ auto x; // { dg-error "auto" }
// deduction, the program is ill-formed.
auto i = 42, j = 42.0; // { dg-error "auto" }
-// New CWG issue
-auto a[2] = { 1, 2 }; // { dg-error "6:.a. declared as array of .auto" }
+// CWG issue 2397: [dcl.type.auto.deduct]/2: "T shall not be an array type".
+auto a[2] = { 1, 2 }; // { dg-error "20:unable to deduce" }
template<class T>
struct A { };
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto42.C b/gcc/testsuite/g++.dg/cpp0x/auto42.C
index 8d15fc9..5b2f677 100644
--- a/gcc/testsuite/g++.dg/cpp0x/auto42.C
+++ b/gcc/testsuite/g++.dg/cpp0x/auto42.C
@@ -5,5 +5,5 @@
void foo(int i)
{
- auto x[1] = { 0 }; // { dg-error "8:.x. declared as array of .auto" }
+ auto x[1] = { 0 }; // { dg-error "19:unable to deduce" }
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist75.C b/gcc/testsuite/g++.dg/cpp0x/initlist75.C
index 9a45087..f572f51 100644
--- a/gcc/testsuite/g++.dg/cpp0x/initlist75.C
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist75.C
@@ -3,4 +3,4 @@
#include <initializer_list>
-auto foo[] = {}; // { dg-error "6:.foo. declared as array of .auto" }
+auto foo[] = {}; // { dg-error "15:unable to deduce" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist80.C b/gcc/testsuite/g++.dg/cpp0x/initlist80.C
index 15723be..a6ab40c 100644
--- a/gcc/testsuite/g++.dg/cpp0x/initlist80.C
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist80.C
@@ -3,4 +3,4 @@
#include <initializer_list>
-auto x[2] = {}; // { dg-error "6:.x. declared as array of .auto" }
+auto x[2] = {}; // { dg-error "14:unable to deduce" }
diff --git a/gcc/testsuite/g++.dg/cpp23/auto-array.C b/gcc/testsuite/g++.dg/cpp23/auto-array.C
new file mode 100644
index 0000000..42f2b0c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/auto-array.C
@@ -0,0 +1,36 @@
+// PR c++/100975
+// DR 2397 - auto specifier for pointers and references to arrays
+// { dg-do compile { target c++11 } }
+
+struct false_type { static constexpr bool value = false; };
+struct true_type { static constexpr bool value = true; };
+template<class T, class U>
+struct is_same : false_type {};
+template<class T>
+struct is_same<T, T> : true_type {};
+
+using U = int[3];
+
+void
+g ()
+{
+ int a[3];
+ auto (*p)[3] = &a;
+ auto (&r)[3] = a;
+ int aa[3][3];
+ auto (*pp)[3][3] = &aa;
+ auto (&rr)[3][3] = aa;
+
+ auto (&&rv)[3] = U{};
+
+ static_assert (is_same<decltype (p), int(*)[3]>::value, "");
+ static_assert (is_same<decltype (pp), int(*)[3][3]>::value, "");
+ static_assert (is_same<decltype (r), int(&)[3]>::value, "");
+ static_assert (is_same<decltype (rv), int(&&)[3]>::value, "");
+ static_assert (is_same<decltype (rr), int(&)[3][3]>::value, "");
+
+#if __cplusplus >= 201402L
+ // In a generic lambda parameter this was OK even before.
+ auto l = [](auto (&arr)[5]) { return arr[0]; };
+#endif
+}
diff --git a/gcc/testsuite/g++.dg/diagnostic/auto1.C b/gcc/testsuite/g++.dg/diagnostic/auto1.C
index ee2eefd..9d9979e 100644
--- a/gcc/testsuite/g++.dg/diagnostic/auto1.C
+++ b/gcc/testsuite/g++.dg/diagnostic/auto1.C
@@ -1,4 +1,5 @@
// PR c++/86915
// { dg-do compile { target c++17 } }
+// Allowed since DR2397.
-template<auto [1]> struct S; // { dg-error "creating array of .auto." }
+template<auto [1]> struct S;