Bug 88128 - G++ should implement CWG 330
Summary: G++ should implement CWG 330
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 9.0
: P3 normal
Target Milestone: ---
Assignee: Marek Polacek
URL:
Keywords: rejects-valid
Depends on:
Blocks: c++-core-issues 91364
  Show dependency treegraph
 
Reported: 2018-11-21 09:05 UTC by Viktor Ostashevskyi
Modified: 2020-03-30 15:50 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-11-21 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Viktor Ostashevskyi 2018-11-21 09:05:36 UTC
GCC rejects following code:


int* (*xx)[];
const int* const(*yy)[];
yy = xx;


while Clang started accepting since 7.0 when they implemented CWG 330.

Without this it is very hard to implement std::span, as its constructors availability are defined in terms of pointer to array convertibility (see [span.cons]).
Comment 1 Jonathan Wakely 2018-11-21 10:32:00 UTC
Confirmed.

[Moved to DR as N4261 at the November, 2014 meeting.]

The resolution is in https://wg21.link/n4261
Comment 2 Viktor Ostashevskyi 2018-11-21 14:01:10 UTC
Actually, even current C++17 unique_ptr::reset for array objects is defined in terms of pointer to array convertibility ([unique.ptr.runtime.modifiers]).
Comment 3 Viktor Ostashevskyi 2019-09-06 08:46:46 UTC
I see that std::span implementation was proposed in https://gcc.gnu.org/ml/libstdc++/2019-08/msg00068.html.

Was this bug fixed for implenting it?

Is it possible to make std::span<const T> from std::vector<T>?
Comment 4 Jonathan Wakely 2019-09-06 10:27:12 UTC
(In reply to Viktor Ostashevskyi from comment #3)
> Was this bug fixed for implenting it?

No.

> Is it possible to make std::span<const T> from std::vector<T>?

Yes, that works with current trunk.
Comment 5 Jonathan Wakely 2019-09-06 11:07:58 UTC
(In reply to Jonathan Wakely from comment #4)
> (In reply to Viktor Ostashevskyi from comment #3)
> > Is it possible to make std::span<const T> from std::vector<T>?
> 
> Yes, that works with current trunk.

Although that could be a bug: the constraints use declval<_Container&>() but should be using declval<const _Container&>().
Comment 6 Marek Polacek 2019-10-09 14:01:45 UTC
I think I have a patch; e.g. this now compiles:

double *const (*d)[3];
double const *const (*e)[3] = d;
int *(*f)[3];
const int *const (*g)[3] = f;

int main()
{
     double *array2D[2][3];
  
     double       *       (*array2DPtr1)[3] = array2D;     // Legal
     double       * const (*array2DPtr2)[3] = array2DPtr1; // Legal
     double const * const (*array2DPtr3)[3] = array2DPtr2; // Illegal
}
Comment 7 Marek Polacek 2019-10-09 20:58:31 UTC
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
Comment 8 Marek Polacek 2019-10-09 21:01:01 UTC
Implemented for GCC 10.