Hi! The following testcase ICEs on arm, because it is the only cdtor_returns_this target. Normally cp_fold never folds destructor calls because the calls have VOID_TYPE_P return and maybe_constant_value in that case does nothing, and cxx_eval_outermost_constant_expr does something for those only if it is a constructor (then initialized_type returns the type of the object being constructed) or if called with constexpr_dtor = true. Arm is the only exception because there the dtor returns the this pointer and so we attempt to fold it, and run into + for (; remapped; remapped = TREE_CHAIN (remapped)) + if (DECL_NAME (remapped) == in_charge_identifier) + { + /* FIXME destructors unnecessarily have in-charge parameters + even in classes without vbases, map it to 0 for now. */ + gcc_assert (!CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fun))); + ctx->global->put_value (remapped, integer_zero_node); assertion there.
The following patch "fixes" it by trying to handle (not handle actually) the dtor calls on arm the same as on all other targets, but perhaps we instead want to constexpr evaluate them on all targets (with constexpr_dtor = true) and deal somehow with the above assertion. In any case, I think some consistency is desirable even when one target has a weird ABI requirement. Bootstrapped/regtested on x86_64-linux and i686-linux plus tested on the testcase in a cross to arm. 2024-03-26 Jakub Jelinek <ja...@redhat.com> PR c++/114426 * cp-gimplify.cc (cp_fold): Don't call maybe_const_value on CALL_EXPRs to cdtors. * g++.dg/cpp2a/pr114426.C: New test. --- gcc/cp/cp-gimplify.cc.jj 2024-02-23 18:55:05.377594277 +0100 +++ gcc/cp/cp-gimplify.cc 2024-03-22 16:46:49.381442914 +0100 @@ -3395,7 +3395,13 @@ cp_fold (tree x, fold_flags_t flags) Do constexpr expansion of expressions where the call itself is not constant, but the call followed by an INDIRECT_REF is. */ if (callee && DECL_DECLARED_CONSTEXPR_P (callee) - && !flag_no_inline) + && !flag_no_inline + /* Don't invoke it on dtors. On + !targetm.cxx.cdtor_returns_this () it won't do anything as it + has void type, so don't do it on + targetm.cxx.cdtor_returns_this () targets either for + consistency. */ + && !DECL_DESTRUCTOR_P (callee)) { mce_value manifestly_const_eval = mce_unknown; if (flags & ff_mce_false) --- gcc/testsuite/g++.dg/cpp2a/pr114426.C.jj 2024-03-22 16:49:55.650882841 +0100 +++ gcc/testsuite/g++.dg/cpp2a/pr114426.C 2024-03-22 16:48:51.829759997 +0100 @@ -0,0 +1,6 @@ +// PR c++/114426 +// { dg-do compile } + +struct A { virtual ~A (); }; +struct B : virtual A { virtual void foo () = 0; }; +struct C : B { C () {} }; Jakub