From: Marek Polacek Date: Tue, 29 Jun 2021 18:30:51 +0000 (-0400) Subject: c++: DR2397 - auto specifier for * and & to arrays [PR100975] X-Git-Tag: basepoints/gcc-13~6380 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e66d0b7b87d105d24da8c4784a0b907fb6b2c095;p=thirdparty%2Fgcc.git 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. --- diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index fa6af6fec11d..7672947e64a3 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 193f92e977a7..ac1ba24f72d5 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 2cd0520023d7..7cde745ddf22 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 struct A { }; diff --git a/gcc/testsuite/g++.dg/cpp0x/auto42.C b/gcc/testsuite/g++.dg/cpp0x/auto42.C index 8d15fc96f095..5b2f6779aafc 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 9a45087c5e45..f572f5181ad7 100644 --- a/gcc/testsuite/g++.dg/cpp0x/initlist75.C +++ b/gcc/testsuite/g++.dg/cpp0x/initlist75.C @@ -3,4 +3,4 @@ #include -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 15723be16f8b..a6ab40ca3498 100644 --- a/gcc/testsuite/g++.dg/cpp0x/initlist80.C +++ b/gcc/testsuite/g++.dg/cpp0x/initlist80.C @@ -3,4 +3,4 @@ #include -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 000000000000..42f2b0c5cf47 --- /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 +struct is_same : false_type {}; +template +struct is_same : 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::value, ""); + static_assert (is_same::value, ""); + static_assert (is_same::value, ""); + static_assert (is_same::value, ""); + static_assert (is_same::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 ee2eefd59aa0..9d9979e3fdc2 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 struct S; // { dg-error "creating array of .auto." } +template struct S;