* [PATCH] c++: DR2397 - auto specifier for * and & to arrays [PR100975]
@ 2021-06-29 19:25 Marek Polacek
2021-06-29 19:50 ` Jason Merrill
0 siblings, 1 reply; 4+ messages in thread
From: Marek Polacek @ 2021-06-29 19:25 UTC (permalink / raw)
To: Jason Merrill, GCC Patches
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 *.
Bootstrapped/regtested on x86_64-pc-linux-gnu. Does this look OK or
have I missed a case we want to support?
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.
---
gcc/cp/decl.c | 11 --------
gcc/testsuite/g++.dg/cpp0x/auto24.C | 3 ++-
gcc/testsuite/g++.dg/cpp0x/auto3.C | 2 +-
gcc/testsuite/g++.dg/cpp0x/auto42.C | 2 +-
gcc/testsuite/g++.dg/cpp0x/initlist75.C | 2 +-
gcc/testsuite/g++.dg/cpp0x/initlist80.C | 2 +-
gcc/testsuite/g++.dg/cpp23/auto-array.C | 36 +++++++++++++++++++++++++
gcc/testsuite/g++.dg/diagnostic/auto1.C | 3 ++-
8 files changed, 44 insertions(+), 17 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp23/auto-array.C
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index fa6af6fec11..7672947e64a 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 193f92e977a..ac1ba24f72d 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 2cd0520023d..56439408a0b 100644
--- a/gcc/testsuite/g++.dg/cpp0x/auto3.C
+++ b/gcc/testsuite/g++.dg/cpp0x/auto3.C
@@ -10,7 +10,7 @@ auto x; // { dg-error "auto" }
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" }
+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 8d15fc96f09..5b2f6779aaf 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 9a45087c5e4..f572f5181ad 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 15723be16f8..a6ab40ca349 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 00000000000..42f2b0c5cf4
--- /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 ee2eefd59aa..9d9979e3fdc 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;
base-commit: 8a8a7d332d5d01db5aea7336a36d9fd71a679fb1
--
2.31.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] c++: DR2397 - auto specifier for * and & to arrays [PR100975]
2021-06-29 19:25 [PATCH] c++: DR2397 - auto specifier for * and & to arrays [PR100975] Marek Polacek
@ 2021-06-29 19:50 ` Jason Merrill
2021-06-29 22:01 ` Marek Polacek
0 siblings, 1 reply; 4+ messages in thread
From: Jason Merrill @ 2021-06-29 19:50 UTC (permalink / raw)
To: Marek Polacek, GCC Patches
On 6/29/21 3:25 PM, Marek Polacek wrote:
> 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 *.
>
> Bootstrapped/regtested on x86_64-pc-linux-gnu. Does this look OK or
> have I missed a case we want to support?
>
> 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.
> ---
> gcc/cp/decl.c | 11 --------
> gcc/testsuite/g++.dg/cpp0x/auto24.C | 3 ++-
> gcc/testsuite/g++.dg/cpp0x/auto3.C | 2 +-
> gcc/testsuite/g++.dg/cpp0x/auto42.C | 2 +-
> gcc/testsuite/g++.dg/cpp0x/initlist75.C | 2 +-
> gcc/testsuite/g++.dg/cpp0x/initlist80.C | 2 +-
> gcc/testsuite/g++.dg/cpp23/auto-array.C | 36 +++++++++++++++++++++++++
> gcc/testsuite/g++.dg/diagnostic/auto1.C | 3 ++-
> 8 files changed, 44 insertions(+), 17 deletions(-)
> create mode 100644 gcc/testsuite/g++.dg/cpp23/auto-array.C
>
> diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
> index fa6af6fec11..7672947e64a 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 193f92e977a..ac1ba24f72d 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 2cd0520023d..56439408a0b 100644
> --- a/gcc/testsuite/g++.dg/cpp0x/auto3.C
> +++ b/gcc/testsuite/g++.dg/cpp0x/auto3.C
> @@ -10,7 +10,7 @@ auto x; // { dg-error "auto" }
> auto i = 42, j = 42.0; // { dg-error "auto" }
>
> // New CWG issue
Let's at least update this comment to quote [dcl.type.auto.deduct]/2: "T
shall not be an array type". I guess "unable to deduce" is a suitable
diagnostic for that error.
> -auto a[2] = { 1, 2 }; // { dg-error "6:.a. declared as array of .auto" }
> +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 8d15fc96f09..5b2f6779aaf 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 9a45087c5e4..f572f5181ad 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 15723be16f8..a6ab40ca349 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 00000000000..42f2b0c5cf4
> --- /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 ee2eefd59aa..9d9979e3fdc 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.
Well, not really; any attempt to use this template should hit the same
problem as above of trying to do auto deduction where T is an array
type. Please add to the testcase to get the error.
> -template<auto [1]> struct S; // { dg-error "creating array of .auto." }
> +template<auto [1]> struct S;
>
> base-commit: 8a8a7d332d5d01db5aea7336a36d9fd71a679fb1
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] c++: DR2397 - auto specifier for * and & to arrays [PR100975]
2021-06-29 19:50 ` Jason Merrill
@ 2021-06-29 22:01 ` Marek Polacek
2021-06-30 13:30 ` Jason Merrill
0 siblings, 1 reply; 4+ messages in thread
From: Marek Polacek @ 2021-06-29 22:01 UTC (permalink / raw)
To: Jason Merrill; +Cc: GCC Patches
On Tue, Jun 29, 2021 at 03:50:27PM -0400, Jason Merrill wrote:
> On 6/29/21 3:25 PM, Marek Polacek wrote:
> > --- a/gcc/testsuite/g++.dg/cpp0x/auto3.C
> > +++ b/gcc/testsuite/g++.dg/cpp0x/auto3.C
> > @@ -10,7 +10,7 @@ auto x; // { dg-error "auto" }
> > auto i = 42, j = 42.0; // { dg-error "auto" }
> > // New CWG issue
>
> Let's at least update this comment to quote [dcl.type.auto.deduct]/2: "T
> shall not be an array type". I guess "unable to deduce" is a suitable
> diagnostic for that error.
Fixed.
> > diff --git a/gcc/testsuite/g++.dg/diagnostic/auto1.C b/gcc/testsuite/g++.dg/diagnostic/auto1.C
> > index ee2eefd59aa..9d9979e3fdc 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.
>
> Well, not really; any attempt to use this template should hit the same
> problem as above of trying to do auto deduction where T is an array type.
> Please add to the testcase to get the error.
Hmm, this
template<auto [1]> struct S { };
static int arr[1];
S<arr> s;
won't give an error: I think it's because we coerce the auto tparm into 'auto*'
before deducing and so don't get the type mismatch error. That seems to be
in line with how 'template<int [1]>' works, though.
So I think we don't need to change this in the patch. Do you agree?
Marek
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] c++: DR2397 - auto specifier for * and & to arrays [PR100975]
2021-06-29 22:01 ` Marek Polacek
@ 2021-06-30 13:30 ` Jason Merrill
0 siblings, 0 replies; 4+ messages in thread
From: Jason Merrill @ 2021-06-30 13:30 UTC (permalink / raw)
To: Marek Polacek; +Cc: GCC Patches
On 6/29/21 6:01 PM, Marek Polacek wrote:
> On Tue, Jun 29, 2021 at 03:50:27PM -0400, Jason Merrill wrote:
>> On 6/29/21 3:25 PM, Marek Polacek wrote:
>>> --- a/gcc/testsuite/g++.dg/cpp0x/auto3.C
>>> +++ b/gcc/testsuite/g++.dg/cpp0x/auto3.C
>>> @@ -10,7 +10,7 @@ auto x; // { dg-error "auto" }
>>> auto i = 42, j = 42.0; // { dg-error "auto" }
>>> // New CWG issue
>>
>> Let's at least update this comment to quote [dcl.type.auto.deduct]/2: "T
>> shall not be an array type". I guess "unable to deduce" is a suitable
>> diagnostic for that error.
>
> Fixed.
>
>>> diff --git a/gcc/testsuite/g++.dg/diagnostic/auto1.C b/gcc/testsuite/g++.dg/diagnostic/auto1.C
>>> index ee2eefd59aa..9d9979e3fdc 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.
>>
>> Well, not really; any attempt to use this template should hit the same
>> problem as above of trying to do auto deduction where T is an array type.
>> Please add to the testcase to get the error.
>
> Hmm, this
>
> template<auto [1]> struct S { };
> static int arr[1];
> S<arr> s;
>
> won't give an error: I think it's because we coerce the auto tparm into 'auto*'
> before deducing and so don't get the type mismatch error. That seems to be
> in line with how 'template<int [1]>' works, though.
Ah, good point.
> So I think we don't need to change this in the patch. Do you agree?
Yes, the patch is OK with the earlier comment tweak.
Jason
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-06-30 13:30 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-29 19:25 [PATCH] c++: DR2397 - auto specifier for * and & to arrays [PR100975] Marek Polacek
2021-06-29 19:50 ` Jason Merrill
2021-06-29 22:01 ` Marek Polacek
2021-06-30 13:30 ` Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).