PR c++/90532 Ensure __is_constructible(T[]) is false
An array of an unknown bound is an incomplete type, so no object of such a type can be constructed. This means __is_constructible should always be false for an array of unknown bound. This patch also changes the std::is_default_constructible trait to use std::is_constructible, which now gives the right answer for arrays of unknown bound. gcc/cp: PR c++/90532 Ensure __is_constructible(T[]) is false * method.c (is_xible_helper): Return error_mark_node for construction of an array of unknown bound. gcc/testsuite: PR c++/90532 Ensure __is_constructible(T[]) is false * g++.dg/ext/90532.C: New test. libstdc++-v3: PR c++/90532 Ensure __is_constructible(T[]) is false * include/std/type_traits (__do_is_default_constructible_impl) (__is_default_constructible_atom, __is_default_constructible_safe): Remove. (is_default_constructible): Use is_constructible. * testsuite/20_util/is_constructible/value.cc: Check int[] case. * testsuite/20_util/is_default_constructible/value.cc: Likewise. * testsuite/20_util/is_trivially_constructible/value.cc: Likewise. * testsuite/20_util/is_trivially_default_constructible/value.cc: Likewise. From-SVN: r271412
This commit is contained in:
parent
eefa592aa0
commit
58487c21b6
@ -1,3 +1,9 @@
|
||||
2019-05-20 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR c++/90532 Ensure __is_constructible(T[]) is false
|
||||
* method.c (is_xible_helper): Return error_mark_node for construction
|
||||
of an array of unknown bound.
|
||||
|
||||
2019-05-17 Thomas Schwinge <thomas@codesourcery.com>
|
||||
|
||||
PR c++/89433
|
||||
|
@ -1201,6 +1201,8 @@ is_xible_helper (enum tree_code code, tree to, tree from, bool trivial)
|
||||
expr = assignable_expr (to, from);
|
||||
else if (trivial && from && TREE_CHAIN (from))
|
||||
return error_mark_node; // only 0- and 1-argument ctors can be trivial
|
||||
else if (TREE_CODE (to) == ARRAY_TYPE && !TYPE_DOMAIN (to))
|
||||
return error_mark_node; // can't construct an array of unknown bound
|
||||
else
|
||||
expr = constructible_expr (to, from);
|
||||
return expr;
|
||||
|
@ -1,3 +1,8 @@
|
||||
2019-05-20 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR c++/90532 Ensure __is_constructible(T[]) is false
|
||||
* g++.dg/ext/90532.C: New test.
|
||||
|
||||
2019-05-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gcc.target/i386/avx512f-simd-1.c: New test.
|
||||
|
27
gcc/testsuite/g++.dg/ext/90532.C
Normal file
27
gcc/testsuite/g++.dg/ext/90532.C
Normal file
@ -0,0 +1,27 @@
|
||||
// { dg-do compile { target c++11 } }
|
||||
// PR c++/90532
|
||||
static_assert( !__is_constructible(int[]), "" );
|
||||
static_assert( !__is_constructible(int[], int), "" );
|
||||
static_assert( !__is_constructible(int[], int[]), "" );
|
||||
static_assert( !__is_trivially_constructible(int[]), "" );
|
||||
static_assert( !__is_trivially_constructible(int[], int), "" );
|
||||
static_assert( !__is_trivially_constructible(int[], int[]), "" );
|
||||
static_assert( !__is_trivially_constructible(int[], int(&)[]), "" );
|
||||
static_assert( !__is_trivially_constructible(int[], void), "" );
|
||||
struct A { };
|
||||
static_assert( !__is_constructible(A[]), "" );
|
||||
static_assert( !__is_constructible(A[], const A&), "" );
|
||||
static_assert( !__is_constructible(A[], const A[]), "" );
|
||||
static_assert( !__is_trivially_constructible(A[]), "" );
|
||||
static_assert( !__is_trivially_constructible(A[], const A&), "" );
|
||||
static_assert( !__is_trivially_constructible(A[], const A[]), "" );
|
||||
static_assert( !__is_trivially_constructible(A[], A(&)[]), "" );
|
||||
static_assert( !__is_trivially_constructible(A[], void), "" );
|
||||
struct B { B(); };
|
||||
static_assert( !__is_constructible(B[]), "" );
|
||||
static_assert( !__is_constructible(B[], const B&), "" );
|
||||
static_assert( !__is_trivially_constructible(B[]), "" );
|
||||
static_assert( !__is_trivially_constructible(B[], const B&), "" );
|
||||
static_assert( !__is_trivially_constructible(B[], const B[]), "" );
|
||||
static_assert( !__is_trivially_constructible(B[], B(&)[]), "" );
|
||||
static_assert( !__is_trivially_constructible(B[], void), "" );
|
@ -1,3 +1,16 @@
|
||||
2019-05-20 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR c++/90532 Ensure __is_constructible(T[]) is false
|
||||
* include/std/type_traits (__do_is_default_constructible_impl)
|
||||
(__is_default_constructible_atom, __is_default_constructible_safe):
|
||||
Remove.
|
||||
(is_default_constructible): Use is_constructible.
|
||||
* testsuite/20_util/is_constructible/value.cc: Check int[] case.
|
||||
* testsuite/20_util/is_default_constructible/value.cc: Likewise.
|
||||
* testsuite/20_util/is_trivially_constructible/value.cc: Likewise.
|
||||
* testsuite/20_util/is_trivially_default_constructible/value.cc:
|
||||
Likewise.
|
||||
|
||||
2019-05-20 Pádraig Brady <pbrady@fb.com>
|
||||
|
||||
* libstdc++-v3/include/ext/new_allocator.h (deallocate): Pass the size
|
||||
|
@ -878,58 +878,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
: public __is_nt_destructible_safe<_Tp>::type
|
||||
{ };
|
||||
|
||||
struct __do_is_default_constructible_impl
|
||||
{
|
||||
template<typename _Tp, typename = decltype(_Tp())>
|
||||
static true_type __test(int);
|
||||
|
||||
template<typename>
|
||||
static false_type __test(...);
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
struct __is_default_constructible_impl
|
||||
: public __do_is_default_constructible_impl
|
||||
{
|
||||
typedef decltype(__test<_Tp>(0)) type;
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
struct __is_default_constructible_atom
|
||||
: public __and_<__not_<is_void<_Tp>>,
|
||||
__is_default_constructible_impl<_Tp>>
|
||||
{ };
|
||||
|
||||
template<typename _Tp, bool = is_array<_Tp>::value>
|
||||
struct __is_default_constructible_safe;
|
||||
|
||||
// The following technique is a workaround for a current core language
|
||||
// restriction, which does not allow for array types to occur in
|
||||
// functional casts of the form T(). Complete arrays can be default-
|
||||
// constructed, if the element type is default-constructible, but
|
||||
// arrays with unknown bounds are not.
|
||||
template<typename _Tp>
|
||||
struct __is_default_constructible_safe<_Tp, true>
|
||||
: public __and_<__is_array_known_bounds<_Tp>,
|
||||
__is_default_constructible_atom<typename
|
||||
remove_all_extents<_Tp>::type>>
|
||||
{ };
|
||||
|
||||
template<typename _Tp>
|
||||
struct __is_default_constructible_safe<_Tp, false>
|
||||
: public __is_default_constructible_atom<_Tp>::type
|
||||
/// is_constructible
|
||||
template<typename _Tp, typename... _Args>
|
||||
struct is_constructible
|
||||
: public __bool_constant<__is_constructible(_Tp, _Args...)>
|
||||
{ };
|
||||
|
||||
/// is_default_constructible
|
||||
template<typename _Tp>
|
||||
struct is_default_constructible
|
||||
: public __is_default_constructible_safe<_Tp>::type
|
||||
{ };
|
||||
|
||||
/// is_constructible
|
||||
template<typename _Tp, typename... _Args>
|
||||
struct is_constructible
|
||||
: public __bool_constant<__is_constructible(_Tp, _Args...)>
|
||||
: public is_constructible<_Tp>::type
|
||||
{ };
|
||||
|
||||
template<typename _Tp, bool = __is_referenceable<_Tp>::value>
|
||||
|
@ -35,4 +35,11 @@ void test01()
|
||||
static_assert(test_property<is_constructible, ExplicitClass>(false), "");
|
||||
static_assert(test_property<is_constructible, ExplicitClass,
|
||||
int, double>(false), "");
|
||||
static_assert(test_property<is_constructible, int[]>(false), "PR c++/90532");
|
||||
static_assert(test_property<is_constructible,
|
||||
__gnu_test::construct::Empty[]>(false), "PR c++/90532");
|
||||
static_assert(test_property<is_constructible,
|
||||
__gnu_test::construct::Ukn[]>(false), "PR c++/90532");
|
||||
static_assert(test_property<is_constructible,
|
||||
__gnu_test::construct::nAny[]>(false), "PR c++/90532");
|
||||
}
|
||||
|
@ -138,3 +138,13 @@ static_assert(!std::is_default_constructible<DelCopy>::value, "Error");
|
||||
static_assert(!std::is_default_constructible<const DelCopy>::value, "Error");
|
||||
static_assert(!std::is_default_constructible<DelDtor>::value, "Error");
|
||||
static_assert(!std::is_default_constructible<const DelDtor>::value, "Error");
|
||||
|
||||
static_assert(!std::is_default_constructible<int[]>::value, "PR c++/90532");
|
||||
static_assert(!std::is_default_constructible<Empty[]>::value, "PR c++/90532");
|
||||
static_assert(!std::is_default_constructible<B[]>::value, "PR c++/90532");
|
||||
static_assert(!std::is_default_constructible<D[]>::value, "PR c++/90532");
|
||||
static_assert(!std::is_default_constructible<U[]>::value, "PR c++/90532");
|
||||
static_assert(!std::is_default_constructible<Ukn[]>::value, "PR c++/90532");
|
||||
static_assert(!std::is_default_constructible<Ellipsis[]>::value, "PR c++/90532");
|
||||
static_assert(!std::is_default_constructible<Any[]>::value, "PR c++/90532");
|
||||
static_assert(!std::is_default_constructible<nAny[]>::value, "PR c++/90532");
|
||||
|
@ -180,4 +180,6 @@ void test01()
|
||||
MoveOnly, const MoveOnly&>(false), "");
|
||||
static_assert(test_property<is_trivially_constructible,
|
||||
MoveOnly2>(false), "");
|
||||
static_assert(test_property<is_trivially_constructible,
|
||||
int[]>(false), "PR c++/90532");
|
||||
}
|
||||
|
@ -62,4 +62,13 @@ void test01()
|
||||
construct::Nontrivial>(false), "");
|
||||
static_assert(test_category<is_trivially_default_constructible,
|
||||
HasTemplateCtor>(true), "");
|
||||
|
||||
static_assert(test_category<is_trivially_default_constructible,
|
||||
int[]>(false), "PR c++/90532");
|
||||
struct A { };
|
||||
static_assert(test_category<is_trivially_default_constructible,
|
||||
A[]>(false), "PR c++/90532");
|
||||
struct B { B() { } };
|
||||
static_assert(test_category<is_trivially_default_constructible,
|
||||
B[]>(false), "PR c++/90532");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user