Bootstrapped/regtested on x86_64-pc-linux-gnu.

-- >8 --
eval_is_explicit_object_parameter() determines whether a parameter is
an explicit object parameter by checking whether the passed-in tree
node is the first parameter in its parameter chain. As described in
the comment for maybe_update_funtion_parm(), if the sequence is
declaration -> reflection -> definition, the old PARM_DECL will be
compared against the new PARM_DECL, causing the check to produce an
incorrect result.
Calling maybe_update_function_parm() before the comparison updates
the old reflection to the new PARM_DECL in the chain, thereby
avoiding this error.

gcc/cp/ChangeLog:

        * reflect.cc (eval_is_explicit_object_parameter): Call
        maybe_update_function_parm before checking the parameter
        against DECL_ARGUMENTS.

gcc/testsuite/ChangeLog:

        * g++.dg/reflect/is_explicit_object_parameter2.C: New test.

Signed-off-by: Wang Jinghao <[email protected]>
---
 gcc/cp/reflect.cc                               | 10 ++++++----
 .../reflect/is_explicit_object_parameter2.C     | 17 +++++++++++++++++
 2 files changed, 23 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/reflect/is_explicit_object_parameter2.C

diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc
index 673b79d0bde..2c2a5972222 100644
--- a/gcc/cp/reflect.cc
+++ b/gcc/cp/reflect.cc
@@ -1828,11 +1828,13 @@ eval_is_data_member_spec (const_tree r, reflect_kind 
kind)
    object parameter.  Otherwise, false.  */
 
 static tree
-eval_is_explicit_object_parameter (const_tree r, reflect_kind kind)
+eval_is_explicit_object_parameter (tree r, reflect_kind kind)
 {
-  if (eval_is_function_parameter (r, kind) == boolean_true_node
-      && r == DECL_ARGUMENTS (DECL_CONTEXT (r))
-      && DECL_XOBJ_MEMBER_FUNCTION_P (DECL_CONTEXT (r)))
+  if (eval_is_function_parameter (r, kind) == boolean_false_node)
+    return boolean_false_node;
+  r = maybe_update_function_parm (r);
+  tree fn = DECL_CONTEXT (r);
+  if (r == DECL_ARGUMENTS (fn) && DECL_XOBJ_MEMBER_FUNCTION_P (fn))
     return boolean_true_node;
   else
     return boolean_false_node;
diff --git a/gcc/testsuite/g++.dg/reflect/is_explicit_object_parameter2.C 
b/gcc/testsuite/g++.dg/reflect/is_explicit_object_parameter2.C
new file mode 100644
index 00000000000..cc24e439bc8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/reflect/is_explicit_object_parameter2.C
@@ -0,0 +1,17 @@
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+// Test std::meta::is_explicit_object_parameter.
+
+#include <meta>
+
+using namespace std::meta;
+
+struct S {
+  void f (this S, int);
+};
+
+constexpr auto p = parameters_of (^^S::f)[0];
+
+void S::f (this S, int) {}
+
+static_assert (is_explicit_object_parameter (p));
-- 
2.52.0

Reply via email to