]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: evaluation order of xobj memfn call [PR123989]
authorPatrick Palka <ppalka@redhat.com>
Thu, 12 Feb 2026 19:44:56 +0000 (14:44 -0500)
committerPatrick Palka <ppalka@redhat.com>
Thu, 12 Feb 2026 19:44:56 +0000 (14:44 -0500)
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 <polacek@redhat.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
gcc/cp/cp-gimplify.cc
gcc/testsuite/g++.dg/cpp23/explicit-obj-eval-order.C [new file with mode: 0644]

index 9d96ce99ea928809c986181091f6d319a7faccfa..2e2f328079a8a6ebbc7b76ac87c3c8d311bc3cc8 100644 (file)
@@ -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 (file)
index 0000000..7ce81f3
--- /dev/null
@@ -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);
+}