]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++/reflection: erroneous access check on dependent splice [PR124989]
authorMarek Polacek <polacek@redhat.com>
Wed, 22 Apr 2026 21:17:05 +0000 (17:17 -0400)
committerMarek Polacek <polacek@redhat.com>
Thu, 23 Apr 2026 15:10:02 +0000 (11:10 -0400)
When processing &[:R:] in cp_parser_splice_expression, we call
build_offset_ref with access checking turned off via push_ and
pop_deferring_access_checks, but the same pair of calls is not
present around the call to build_offset_ref in tsubst_splice_expr
and so the following test fails to compile due to access control
checking failures.

PR c++/124989

gcc/cp/ChangeLog:

* pt.cc (tsubst_splice_expr): Turn off access checking for the
build_offset_ref call.

gcc/testsuite/ChangeLog:

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

Reviewed-by: Patrick Palka <ppalka@redhat.com>
gcc/cp/pt.cc
gcc/testsuite/g++.dg/reflect/member24.C [new file with mode: 0644]

index 551c8bcbb682cf1e23d307925f36a9d6a22294a0..fca63d3950dd6fba5d2ea0daf9d450f0abd23608 100644 (file)
@@ -16957,12 +16957,14 @@ tsubst_splice_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
   if (SPLICE_EXPR_ADDRESS_P (t))
     {
+      push_deferring_access_checks (dk_no_check);
       if (BASELINK_P (op))
        op = build_offset_ref (BINFO_TYPE (BASELINK_ACCESS_BINFO (op)), op,
                               /*address_p=*/true, complain);
       else if (DECL_NONSTATIC_MEMBER_P (op))
        op = build_offset_ref (DECL_CONTEXT (op), op,
                               /*address_p=*/true, complain);
+      pop_deferring_access_checks ();
     }
 
   if (outer_automatic_var_p (op))
diff --git a/gcc/testsuite/g++.dg/reflect/member24.C b/gcc/testsuite/g++.dg/reflect/member24.C
new file mode 100644 (file)
index 0000000..461b8b3
--- /dev/null
@@ -0,0 +1,25 @@
+// PR c++/124989
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+
+using info = decltype(^^::);
+
+template <info R>
+constexpr auto pointer_of()
+{
+  return &[: R :];
+}
+
+struct X
+{
+    int a;
+protected:
+    int b;
+private:
+    int c;
+
+public:
+    static constexpr auto pa = pointer_of<^^X::a>();
+    static constexpr auto pb = pointer_of<^^X::b>();
+    static constexpr auto pc = pointer_of<^^X::c>();
+};