c++: make __is_constructible work with paren-init of aggrs [PR94149]
authorMarek Polacek <polacek@redhat.com>
Thu, 9 Apr 2020 20:31:59 +0000 (16:31 -0400)
committerMarek Polacek <polacek@redhat.com>
Fri, 10 Apr 2020 17:54:12 +0000 (13:54 -0400)
commit62c25d7adb1a5664982449dda0e7f9ca63cf4735
tree1886e04120a6fcb60d364bedc5960ee16d1bc451
parente26bd694c790b7c8f68c6736b2683c60a8fcbcfe
c++: make __is_constructible work with paren-init of aggrs [PR94149]

In C++20 this is well-formed:

  using T = int[2];
  T t(1, 2);

which means that std::is_constructible_v<int[2], int, int> should be true.
But constructible_expr immediately returned the error_mark_node when it
saw a list with more than one element.  To give accurate results in
C++20, we have to try initializing the aggregate from a parenthesized list of
values.

To not repeat the same mistake as in c++/93790, if there's only one
element, I'm trying {} only when () didn't succeed.  is_constructible5.C
verifies this.

In paren-init24.C std::is_nothrow_constructible_v doesn't work due to
 error: invalid 'static_cast' from type 'int' to type 'int [1]'
and
 error: functional cast to array type 'int [2]'

This needs to be fixed in libstdc++.

PR c++/94149
* method.c (constructible_expr): In C++20, try using parenthesized
initialization of aggregates to determine the result of
__is_constructible.

* g++.dg/cpp2a/paren-init24.C: New test.
* g++.dg/cpp2a/paren-init25.C: New test.
* g++.dg/ext/is_constructible5.C: New test.
gcc/cp/ChangeLog
gcc/cp/method.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp2a/paren-init24.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/paren-init25.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/is_constructible5.C [new file with mode: 0644]