Summary: | Implement P0388R4: Permit conversions to arrays of unknown bound | ||
---|---|---|---|
Product: | gcc | Reporter: | Marek Polacek <mpolacek> |
Component: | c++ | Assignee: | Marek Polacek <mpolacek> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | redi, webrown.cpp |
Priority: | P3 | Keywords: | patch |
Version: | 10.0 | ||
Target Milestone: | --- | ||
Host: | Target: | ||
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | 2019-08-05 00:00:00 | |
Bug Depends on: | 69531, 88128, 91844 | ||
Bug Blocks: | 88323 |
Description
Marek Polacek
2019-08-05 16:35:22 UTC
Sort of depends on CWG 2352 Similar types and reference binding which changed the definition of "reference-related". Workin' on it. Note to myself: while messing with this, perhaps implement DR 330 too for good measure. Bug 88128. Author: mpolacek Date: Wed Oct 9 20:58:00 2019 New Revision: 276771 URL: https://gcc.gnu.org/viewcvs?rev=276771&root=gcc&view=rev Log: Implement C++20 P0388R4, DR 1307, and DR 330. This patch implements P0388R4, Permit conversions to arrays of unknown bound, <http://wg21.link/p0388r4>. CWG 393 allowed references to arrays of unknown bound and this C++20 feature allows conversions like void f(int(&)[]); int arr[1]; void g() { f(arr); } int(&r)[] = arr; The proposal seemed fairly straightforward but it turned out to be quite shifty. I found out that I needed to implement DR 2352 (done), and also DR 1307 (done in this patch). The latter DR added wording for list-initialization ranking of references to arrays which this proposal extends. DR 330 was also implemented in this patch. PR c++/91364 - P0388R4: Permit conversions to arrays of unknown bound. PR c++/69531 - DR 1307: Differently bounded array parameters. PR c++/88128 - DR 330: Qual convs and pointers to arrays of pointers. * call.c (build_array_conv): Build ck_identity at the beginning of the conversion. (standard_conversion): Pass bounds_none to comp_ptr_ttypes_const. (maybe_warn_array_conv): New. (convert_like_real): Call it. Add an error message about converting from arrays of unknown bounds. (conv_get_original_expr): New. (nelts_initialized_by_list_init): New. (conv_binds_to_array_of_unknown_bound): New. (compare_ics): Implement list-initialization ranking based on array sizes, as specified in DR 1307 and P0388R. * cp-tree.h (comp_ptr_ttypes_const): Adjust declaration. (compare_bounds_t): New enum. * typeck.c (comp_array_types): New bool and compare_bounds_t parameters. Use them. (structural_comptypes): Adjust the call to comp_array_types. (similar_type_p): Handle ARRAY_TYPE. (build_const_cast_1): Pass bounds_none to comp_ptr_ttypes_const. (comp_ptr_ttypes_real): Don't check cv-quals of ARRAY_TYPEs. Use comp_array_types to compare array types. Look through arrays as per DR 330. (comp_ptr_ttypes_const): Use comp_array_types to compare array types. Look through arrays as per DR 330. * g++.dg/conversion/qual1.C: New test. * g++.dg/conversion/qual2.C: New test. * g++.dg/conversion/qual3.C: New test. * g++.dg/conversion/ref2.C: New test. * g++.dg/conversion/ref3.C: New test. * g++.dg/cpp0x/initlist-array3.C: Remove dg-error. * g++.dg/cpp0x/initlist-array7.C: New test. * g++.dg/cpp0x/initlist-array8.C: New test. * g++.dg/cpp2a/array-conv1.C: New test. * g++.dg/cpp2a/array-conv10.C: New test. * g++.dg/cpp2a/array-conv11.C: New test. * g++.dg/cpp2a/array-conv12.C: New test. * g++.dg/cpp2a/array-conv13.C: New test. * g++.dg/cpp2a/array-conv14.C: New test. * g++.dg/cpp2a/array-conv15.C: New test. * g++.dg/cpp2a/array-conv16.C: New test. * g++.dg/cpp2a/array-conv17.C: New test. * g++.dg/cpp2a/array-conv2.C: New test. * g++.dg/cpp2a/array-conv3.C: New test. * g++.dg/cpp2a/array-conv4.C: New test. * g++.dg/cpp2a/array-conv5.C: New test. * g++.dg/cpp2a/array-conv6.C: New test. * g++.dg/cpp2a/array-conv7.C: New test. * g++.dg/cpp2a/array-conv8.C: New test. * g++.dg/cpp2a/array-conv9.C: New test. * g++.old-deja/g++.bugs/900321_01.C: Adjust dg-error. * testsuite/23_containers/span/lwg3255.cc: Adjust test to match the post-P0388R4 behavior. Added: trunk/gcc/testsuite/g++.dg/conversion/qual1.C trunk/gcc/testsuite/g++.dg/conversion/qual2.C trunk/gcc/testsuite/g++.dg/conversion/qual3.C trunk/gcc/testsuite/g++.dg/conversion/ref2.C trunk/gcc/testsuite/g++.dg/conversion/ref3.C trunk/gcc/testsuite/g++.dg/cpp0x/initlist-array7.C trunk/gcc/testsuite/g++.dg/cpp0x/initlist-array8.C trunk/gcc/testsuite/g++.dg/cpp2a/array-conv1.C trunk/gcc/testsuite/g++.dg/cpp2a/array-conv10.C trunk/gcc/testsuite/g++.dg/cpp2a/array-conv11.C trunk/gcc/testsuite/g++.dg/cpp2a/array-conv12.C trunk/gcc/testsuite/g++.dg/cpp2a/array-conv13.C trunk/gcc/testsuite/g++.dg/cpp2a/array-conv14.C trunk/gcc/testsuite/g++.dg/cpp2a/array-conv15.C trunk/gcc/testsuite/g++.dg/cpp2a/array-conv16.C trunk/gcc/testsuite/g++.dg/cpp2a/array-conv17.C trunk/gcc/testsuite/g++.dg/cpp2a/array-conv2.C trunk/gcc/testsuite/g++.dg/cpp2a/array-conv3.C trunk/gcc/testsuite/g++.dg/cpp2a/array-conv4.C trunk/gcc/testsuite/g++.dg/cpp2a/array-conv5.C trunk/gcc/testsuite/g++.dg/cpp2a/array-conv6.C trunk/gcc/testsuite/g++.dg/cpp2a/array-conv7.C trunk/gcc/testsuite/g++.dg/cpp2a/array-conv8.C trunk/gcc/testsuite/g++.dg/cpp2a/array-conv9.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c trunk/gcc/cp/cp-tree.h trunk/gcc/cp/typeck.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/g++.dg/cpp0x/initlist-array3.C trunk/gcc/testsuite/g++.old-deja/g++.bugs/900321_01.C trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/testsuite/23_containers/span/lwg3255.cc Implemented for GCC 10. Fails to match for variadic arguments. Reopen or file a new bug? https://godbolt.org/z/zuJagw #include <cstdio> void cat(auto const(&...a)[]); //void cat(auto const(&...)[]); // REJECT error: variable or field // 'cat' declared void void cat(auto const(&)[]...); // ACCEPT: is this well formed? (IDK) void cat(auto const(&a)[]...); // ACCEPT: is this well formed? (IDK) // can't provide a definition // If the char[6] overload below is removed then this [] overload fails: // error: no matching function for call to 'cat(const char [6]...)' void cat(auto const(&...cstr)[]) { (puts(cstr),...); } void cat(auto const(&...cstr)[6]) { (puts(cstr),...); } int main() { cat("Hello","world"); } Reduced example (but still with puts output) https://godbolt.org/z/Ttc2Za #include <cstdio> void cat(auto const(&...cstr)[]) { (puts(cstr),...); } // Comment out this next line[6] void cat(auto const(&...cstr)[6]) { (puts(cstr),...); } int main() { cat("Hello","world"); } Fails to match the 1st overload when the 2nd overload is removed Answering my own question "is this well formed?" void cat(auto const(&a)[]...); Yes; it matches T(&)[] type argument exactly https://godbolt.org/z/NHjPrK The variadic unknown-bound 1st overload matches exact T(&)[] only https://godbolt.org/z/9qZpWX #include <cstdio> void cat(auto const(&...cstr)[]) { (((void)cstr,puts("G'bye")),...); } void cat(auto const(&...cstr)[6]) { (puts(cstr),...); } using punk = char(*)[]; // Pointer to UNKnown-bound char array int main() { cat("Hello"); // Outputs "Hello" via 2nd overload cat(*punk{}); // Outputs "G'bye" via 1st overload } (In reply to Will Wray from comment #7) > Fails to match for variadic arguments. Reopen or file a new bug? Definitely a new bug, please. |