On 2/12/26 5:43 AM, Patrick Palka wrote:
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
OK for trunk/15?
-- >8 --
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 METHOD_TYPE callee evaluation order handling
in cp_gimplify_expr to also handle xobj memfn callees. (The handling
needs to look at both fntype and decl because the callee can be e.g. an
OBJ_TYPE_REF for which decl would be NULL.)
It seems to me that this sequencing is a property of the syntax "a.f ("
([expr.call]/7) rather than of the function; it is not required for e.g.
"(*&A::f) (a, ++a.m)". Though it is still allowed under
"indeterminately sequenced", so this is OK with an added comment.
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.
---
gcc/cp/cp-gimplify.cc | 5 ++++-
.../g++.dg/cpp23/explicit-obj-eval-order.C | 16 ++++++++++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/g++.dg/cpp23/explicit-obj-eval-order.C
diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index 5ccfeefa6982..ba6a65961200 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -921,7 +921,10 @@ 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);
+ 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);
+}