[gcc r16-1054] c++: __is_destructible fixes [PR107600]
Jason Merrill
jason@gcc.gnu.org
Mon Jun 2 15:30:07 GMT 2025
https://gcc.gnu.org/g:d7f33a35bffe7b331b0f8475e52c2dcc1c5d2ea8
commit r16-1054-gd7f33a35bffe7b331b0f8475e52c2dcc1c5d2ea8
Author: Jason Merrill <jason@redhat.com>
Date: Mon Jun 2 10:09:07 2025 -0400
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.
Diff:
---
gcc/cp/method.cc | 21 ++++++++++++++++-----
gcc/testsuite/g++.dg/ext/is_destructible2.C | 15 +++++++++++++++
2 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
index 3a675d9f8723..bb6790f13cdb 100644
--- a/gcc/cp/method.cc
+++ b/gcc/cp/method.cc
@@ -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;
diff --git a/gcc/testsuite/g++.dg/ext/is_destructible2.C b/gcc/testsuite/g++.dg/ext/is_destructible2.C
new file mode 100644
index 000000000000..7f15fc786848
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_destructible2.C
@@ -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()) );
More information about the Gcc-cvs
mailing list