Re: [PATCH 3/3] c++: P1997 array-copy extensions: Assignment, return, etc. [PR103238]
On 11/21/21 21:51, Will Wray via Gcc-patches wrote: This second patch completes the work of the first 'array-copy' patch to provide first-cut implementations of all P1997 features. It adds: * Assignments to arrays from array values,a = b; * Placeholder auto in array declarations, auto cp[] = a; * Array as a return type from functions WIP, auto f() -> T[N]; * Parsing of array pseudo-destructors a.~A() (only parsing for now, untested) Let's not accept the pseudo-destructor and silently ignore it. Either we should delay the parsing change until the semantics are implemented, or parse it and give a sorry(). Assignments a = b were easily allowed by changing branch conditions. Assignments a = {e...} were trickier (a case not mentioned in P1997): int a[16]; a = {0,1,1,2}; a = {}; // assignments from init-lists The semantics is the same as for struct aggregates: (1) Aggregate initialization of an rhs array of the lhs type (so trailing elements with no initializer are value initialized) (2) Copy-initialization of the lhs from the rhs. The special case of an optionally-braced array value is allowed so that a = b and a = {b} are generally equivalent for same type arrays a and b. However, the now special-special case of assignment from a braced string- literal currently only supports exact-match (same as for other arrays): char a[4]; a={"c++"} /* OK */; a={"c"} /* FAILs but should work */; Array return from function is work in progress. The tests show what works. I'm stuck in unfamiliar territory so it's best to submit what I have to be reviewed for hints on how to progress. Let's split out array return into a separate patch for now. It also has ABI implications. Please try the patch; play, stress it, and report the FAILS. PR c++/103238 gcc/c/ChangeLog: * c-decl.c (grokdeclarator): Don't complain of array returns. gcc/cp/ChangeLog: * call.c (can_convert_array): Extend to include array inits. (standard_conversion): No decay for same-type array. Call build_conv. (implicit_conversion_1): Call reshape_init for arrays too. * decl.c (grokdeclarator): Don't complain of array returns. * parser.c (cp_parser_postfix_dot_deref_expression): parse array ~A(). * pt.c (tsubst_function_type): Array type return is not a failure. (do_auto_deduction): Placeholder auto deduction of array element type. * tree.c (lvalue_kind): clk_class should include array (I think?). * typeck.c (cp_build_modify_expr): Call reshape init to strip optional braces. Allow NOP_EXPR for array assignment. (convert_for_assignment): New if-block for same-type array convert, strips optional braces, but rejects STRING_CST rhs shorter than lhs. gcc/testsuite/ChangeLog: * g++.dg/init/array-copy10.C: New test. auto[] deduce 'after' PASSes * g++.dg/init/array-copy11.C: New test. Array return 'before' XFAILs * g++.dg/init/array-copy12.C: New test. Array return 'after' PASSes * g++.dg/init/array-copy7.C: New test. Array assign 'before' XFAILs * g++.dg/init/array-copy8.C: New test. Array assign 'after' PASSes * g++.dg/init/array-copy9.C: New test. auto[] deduce 'before' XFAILs --- gcc/c/c-decl.c | 2 +- gcc/cp/call.c| 43 +++-- gcc/cp/decl.c| 2 +- gcc/cp/parser.c | 4 +- gcc/cp/pt.c | 13 +- gcc/cp/tree.c| 3 +- gcc/cp/typeck.c | 26 +-- gcc/testsuite/g++.dg/init/array-copy10.C | 57 +++ gcc/testsuite/g++.dg/init/array-copy11.C | 13 ++ gcc/testsuite/g++.dg/init/array-copy12.C | 79 gcc/testsuite/g++.dg/init/array-copy7.C | 40 gcc/testsuite/g++.dg/init/array-copy8.C | 56 ++ gcc/testsuite/g++.dg/init/array-copy9.C | 57 +++ 13 files changed, 372 insertions(+), 23 deletions(-) diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 3e28a038095..031c43d189f 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -7055,7 +7055,7 @@ grokdeclarator (const struct c_declarator *declarator, "returning a function"); type = integer_type_node; } - if (TREE_CODE (type) == ARRAY_TYPE) + if (TREE_CODE (type) == ARRAY_TYPE && !flag_array_copy) { if (name) error_at (loc, "%qE declared as function returning an array", diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 4ee21c7bdbd..c73fb73d86e 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -908,29 +908,34 @@ static bool can_convert_array (tree atype, tree from, int flags, tsubst_flags_t complain) { tree elttype = TREE_TYPE (atype); - unsigne
Re: [PATCH 3/3] c++: P1997 array-copy extensions: Assignment, return, etc. [PR103238]
On Mon, Nov 22, 2021 at 3:42 PM Joseph Myers wrote: > > On Sun, 21 Nov 2021, Will Wray via Gcc-patches wrote: > > > gcc/c/ChangeLog: > > > > * c-decl.c (grokdeclarator): Don't complain of array returns. > > A C front-end change like this doesn't belong in a C++ patch Of course, thanks. I'll remove it. Hopefully it'll be back before long, in a compatible C array-copy patchset.
Re: [PATCH 3/3] c++: P1997 array-copy extensions: Assignment, return, etc. [PR103238]
On Sun, 21 Nov 2021, Will Wray via Gcc-patches wrote: > gcc/c/ChangeLog: > > * c-decl.c (grokdeclarator): Don't complain of array returns. A C front-end change like this doesn't belong in a C++ patch (I don't see any reason why this C++ patch would need such a C front-end change, it's not e.g. changing the interface to a function called from shared code but defined separately for both front ends). -- Joseph S. Myers jos...@codesourcery.com
[PATCH 3/3] c++: P1997 array-copy extensions: Assignment, return, etc. [PR103238]
This second patch completes the work of the first 'array-copy' patch to provide first-cut implementations of all P1997 features. It adds: * Assignments to arrays from array values,a = b; * Placeholder auto in array declarations, auto cp[] = a; * Array as a return type from functions WIP, auto f() -> T[N]; * Parsing of array pseudo-destructors a.~A() (only parsing for now, untested) Assignments a = b were easily allowed by changing branch conditions. Assignments a = {e...} were trickier (a case not mentioned in P1997): int a[16]; a = {0,1,1,2}; a = {}; // assignments from init-lists The semantics is the same as for struct aggregates: (1) Aggregate initialization of an rhs array of the lhs type (so trailing elements with no initializer are value initialized) (2) Copy-initialization of the lhs from the rhs. The special case of an optionally-braced array value is allowed so that a = b and a = {b} are generally equivalent for same type arrays a and b. However, the now special-special case of assignment from a braced string- literal currently only supports exact-match (same as for other arrays): char a[4]; a={"c++"} /* OK */; a={"c"} /* FAILs but should work */; Array return from function is work in progress. The tests show what works. I'm stuck in unfamiliar territory so it's best to submit what I have to be reviewed for hints on how to progress. Please try the patch; play, stress it, and report the FAILS. PR c++/103238 gcc/c/ChangeLog: * c-decl.c (grokdeclarator): Don't complain of array returns. gcc/cp/ChangeLog: * call.c (can_convert_array): Extend to include array inits. (standard_conversion): No decay for same-type array. Call build_conv. (implicit_conversion_1): Call reshape_init for arrays too. * decl.c (grokdeclarator): Don't complain of array returns. * parser.c (cp_parser_postfix_dot_deref_expression): parse array ~A(). * pt.c (tsubst_function_type): Array type return is not a failure. (do_auto_deduction): Placeholder auto deduction of array element type. * tree.c (lvalue_kind): clk_class should include array (I think?). * typeck.c (cp_build_modify_expr): Call reshape init to strip optional braces. Allow NOP_EXPR for array assignment. (convert_for_assignment): New if-block for same-type array convert, strips optional braces, but rejects STRING_CST rhs shorter than lhs. gcc/testsuite/ChangeLog: * g++.dg/init/array-copy10.C: New test. auto[] deduce 'after' PASSes * g++.dg/init/array-copy11.C: New test. Array return 'before' XFAILs * g++.dg/init/array-copy12.C: New test. Array return 'after' PASSes * g++.dg/init/array-copy7.C: New test. Array assign 'before' XFAILs * g++.dg/init/array-copy8.C: New test. Array assign 'after' PASSes * g++.dg/init/array-copy9.C: New test. auto[] deduce 'before' XFAILs --- gcc/c/c-decl.c | 2 +- gcc/cp/call.c| 43 +++-- gcc/cp/decl.c| 2 +- gcc/cp/parser.c | 4 +- gcc/cp/pt.c | 13 +- gcc/cp/tree.c| 3 +- gcc/cp/typeck.c | 26 +-- gcc/testsuite/g++.dg/init/array-copy10.C | 57 +++ gcc/testsuite/g++.dg/init/array-copy11.C | 13 ++ gcc/testsuite/g++.dg/init/array-copy12.C | 79 gcc/testsuite/g++.dg/init/array-copy7.C | 40 gcc/testsuite/g++.dg/init/array-copy8.C | 56 ++ gcc/testsuite/g++.dg/init/array-copy9.C | 57 +++ 13 files changed, 372 insertions(+), 23 deletions(-) diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 3e28a038095..031c43d189f 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -7055,7 +7055,7 @@ grokdeclarator (const struct c_declarator *declarator, "returning a function"); type = integer_type_node; } - if (TREE_CODE (type) == ARRAY_TYPE) + if (TREE_CODE (type) == ARRAY_TYPE && !flag_array_copy) { if (name) error_at (loc, "%qE declared as function returning an array", diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 4ee21c7bdbd..c73fb73d86e 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -908,29 +908,34 @@ static bool can_convert_array (tree atype, tree from, int flags, tsubst_flags_t complain) { tree elttype = TREE_TYPE (atype); - unsigned i; if (TREE_CODE (from) == CONSTRUCTOR) { - for (i = 0; i < CONSTRUCTOR_NELTS (from); ++i) + for (auto&& ce : CONSTRUCTOR_ELTS (from)) { - tree val = CONSTRUCTOR_ELT (from, i)->value; - bool ok; - if (TREE_CODE (elttype) == ARRAY_TYPE) - ok = can_convert_array (elttype, val, flags, complain)