mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 03:46:53 -05:00
c++: __is_destructible fixes [PR107600]
destructible_expr was wrongly assuming that TO is a class type. When is_xible_helper was added in r8-742 it returned early for abstract class types, which is correct for __is_constructible, but not __is_assignable or (now) __is_destructible. PR c++/107600 gcc/cp/ChangeLog: * method.cc (destructible_expr): Handle non-classes. (constructible_expr): Check for abstract class here... (is_xible_helper): ...not here. gcc/testsuite/ChangeLog: * g++.dg/ext/is_destructible2.C: New test.
This commit is contained in:
@@ -2251,6 +2251,8 @@ constructible_expr (tree to, tree from)
|
||||
const int len = TREE_VEC_LENGTH (from);
|
||||
if (CLASS_TYPE_P (to))
|
||||
{
|
||||
if (ABSTRACT_CLASS_TYPE_P (to))
|
||||
return error_mark_node;
|
||||
tree ctype = to;
|
||||
vec<tree, va_gc> *args = NULL;
|
||||
if (!TYPE_REF_P (to))
|
||||
@@ -2337,10 +2339,19 @@ destructible_expr (tree to)
|
||||
{
|
||||
cp_unevaluated cp_uneval_guard;
|
||||
int flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR;
|
||||
to = build_trait_object (to);
|
||||
tree r = build_delete (input_location, TREE_TYPE (to), to,
|
||||
sfk_complete_destructor, flags, 0, tf_none);
|
||||
return r;
|
||||
to = strip_array_types (to);
|
||||
if (CLASS_TYPE_P (to))
|
||||
{
|
||||
to = build_trait_object (to);
|
||||
return build_delete (input_location, TREE_TYPE (to), to,
|
||||
sfk_complete_destructor, flags, 0, tf_none);
|
||||
}
|
||||
/* [expr.prim.id.dtor] If the id-expression names a pseudo-destructor, T
|
||||
shall be a scalar type.... */
|
||||
else if (scalarish_type_p (to))
|
||||
return void_node;
|
||||
else
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* Returns a tree iff TO is assignable (if CODE is MODIFY_EXPR) or
|
||||
@@ -2352,7 +2363,7 @@ is_xible_helper (enum tree_code code, tree to, tree from, bool trivial)
|
||||
{
|
||||
to = complete_type (to);
|
||||
deferring_access_check_sentinel acs (dk_no_deferred);
|
||||
if (VOID_TYPE_P (to) || ABSTRACT_CLASS_TYPE_P (to)
|
||||
if (VOID_TYPE_P (to)
|
||||
|| (from && FUNC_OR_METHOD_TYPE_P (from)
|
||||
&& (TYPE_READONLY (from) || FUNCTION_REF_QUALIFIED (from))))
|
||||
return error_mark_node;
|
||||
|
||||
15
gcc/testsuite/g++.dg/ext/is_destructible2.C
Normal file
15
gcc/testsuite/g++.dg/ext/is_destructible2.C
Normal file
@@ -0,0 +1,15 @@
|
||||
// PR c++/107600
|
||||
// { dg-additional-options -Wno-c++17-extensions }
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
struct A
|
||||
{
|
||||
A& operator= (const A&);
|
||||
virtual ~A() = 0;
|
||||
};
|
||||
|
||||
static_assert( __is_destructible(A) );
|
||||
static_assert( __is_assignable(A, A) );
|
||||
static_assert( not __is_destructible(int()) );
|
||||
static_assert( not __is_nothrow_destructible(int()) );
|
||||
static_assert( not __is_trivially_destructible(int()) );
|
||||
Reference in New Issue
Block a user