https://gcc.gnu.org/g:0d51ed19504bcaa540763423763bb97227ed6c1c
commit r16-7487-g0d51ed19504bcaa540763423763bb97227ed6c1c Author: Patrick Palka <[email protected]> Date: Thu Feb 12 14:44:56 2026 -0500 c++: evaluation order of xobj memfn call [PR123989] The object argument of an xobj memfn call needs to be evaluated before its formal arguments, like with an iobj memfn call. This patch generalizes the existing such handling in cp_gimplify_expr for METHOD_TYPE callees to also accept xobj memfn callees. PR c++/123989 gcc/cp/ChangeLog: * cp-gimplify.cc (cp_gimplify_expr) <case CALL_EXPR>: Evaluate the object argument of an xobj memfn call first too. gcc/testsuite/ChangeLog: * g++.dg/cpp23/explicit-obj-eval-order.C: New test. Reviewed-by: Marek Polacek <[email protected]> Reviewed-by: Jason Merrill <[email protected]> Diff: --- gcc/cp/cp-gimplify.cc | 9 ++++++++- gcc/testsuite/g++.dg/cpp23/explicit-obj-eval-order.C | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc index 9d96ce99ea92..2e2f328079a8 100644 --- a/gcc/cp/cp-gimplify.cc +++ b/gcc/cp/cp-gimplify.cc @@ -921,7 +921,14 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) tree fntype = TREE_TYPE (CALL_EXPR_FN (*expr_p)); if (INDIRECT_TYPE_P (fntype)) fntype = TREE_TYPE (fntype); - if (TREE_CODE (fntype) == METHOD_TYPE) + tree decl = cp_get_callee_fndecl_nofold (*expr_p); + /* We can't just rely on 'decl' because virtual function callees + are expressed as OBJ_TYPE_REF. Though checking for METHOD_TYPE + means we'll also sequence PMF calls, which is allowed under + "indeterminately sequenced". */ + if (TREE_CODE (fntype) == METHOD_TYPE + || (decl && DECL_LANG_SPECIFIC (decl) + && DECL_XOBJ_MEMBER_FUNCTION_P (decl))) { int nargs = call_expr_nargs (*expr_p); bool side_effects = false; diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-eval-order.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-eval-order.C new file mode 100644 index 000000000000..7ce81f32cc4b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-eval-order.C @@ -0,0 +1,16 @@ +// PR c++/123989 +// { dg-do run { target c++23 } } + +struct A { + int m = 42; + + void f(this A self, int n) { + if (self.m != 42 || n != 43) + __builtin_abort(); + } +}; + +int main() { + A a; + a.f(++a.m); +}
