extern tree build_transaction_expr (location_t, tree, int, tree);
extern bool cxx_omp_create_clause_info (tree, tree, bool, bool,
bool, bool);
-extern tree baselink_for_fns (tree);
+extern tree baselink_for_fns (tree, bool = false);
extern void finish_static_assert (tree, tree, location_t,
bool, bool, bool = false);
extern tree finish_decltype_type (tree, bool, tsubst_flags_t);
&& !concept_check_p (t))
t = finish_template_variable (t);
else if (is_overloaded_fn (t))
- t = baselink_for_fns (t);
+ t = baselink_for_fns (t, /*ignore_current_class_p=*/true);
if (cp_parser_parse_definitely (parser))
return get_reflection (loc, t);
}
it comes from e.g. members_of it is not. */
if (DECL_FUNCTION_TEMPLATE_P (refl))
refl = ovl_make (refl, NULL_TREE);
+ /* Also add a BASELINK so that we handle &[:R:]. Since R was already
+ resolved (e.g. via members_of), we don't want to consider the enclosing
+ class for the access path. */
+ if (is_overloaded_fn (refl))
+ refl = baselink_for_fns (refl, /*ignore_current_class_p=*/true);
return refl;
}
/* If FNS is a member function, a set of member functions, or a
template-id referring to one or more member functions, return a
BASELINK for FNS, incorporating the current access context.
- Otherwise, return FNS unchanged. */
+ Otherwise, return FNS unchanged. If IGNORE_CURRENT_CLASS_P is
+ true, we do not consider the currently open derived class. */
tree
-baselink_for_fns (tree fns)
+baselink_for_fns (tree fns, bool ignore_current_class_p/*=false*/)
{
- tree scope;
- tree cl;
-
- if (BASELINK_P (fns)
- || error_operand_p (fns))
+ if (BASELINK_P (fns) || error_operand_p (fns))
return fns;
- scope = ovl_scope (fns);
+ tree scope = ovl_scope (fns);
if (!CLASS_TYPE_P (scope))
return fns;
- cl = currently_open_derived_class (scope);
+ tree cl = (ignore_current_class_p
+ ? NULL_TREE
+ : currently_open_derived_class (scope));
if (!cl)
cl = scope;
tree access_path = TYPE_BINFO (cl);
--- /dev/null
+// PR c++/124794
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+
+#include <meta>
+
+struct C {
+ template <class T> void f(T);
+ void g (int);
+
+ static constexpr int val = 42;
+};
+
+constexpr auto ac = std::meta::access_context::current();
+constexpr auto f1 = members_of(^^C, ac)[0];
+constexpr auto f2 = ^^C::f;
+void (C::*p1)(int) = &template [:f1:];
+void (C::*p2)(int) = &template [:f2:];
+
+constexpr auto g1 = members_of(^^C, ac)[1];
+constexpr auto g2 = ^^C::g;
+void (C::*p3)(int) = &[:g1:];
+void (C::*p4)(int) = &[:g2:];
+
+void
+g (C *pc)
+{
+ auto p = &pc->[: ^^C::val :];
+ auto q = &pc->C::val;
+
+ pc->f (42);
+ pc->template [:f1:](42);
+ pc->template [:f2:](42);
+ pc->g (42);
+ pc->[:g1:] (42);
+ pc->[:g2:] (42);
+}
+
+struct D1 : C {
+ void mfn (D1 *pd)
+ {
+ auto p = &pd->[: ^^C::val :];
+ auto q = &pd->C::val;
+
+ pd->f (42);
+ pd->template [:f1:](42);
+ pd->template [:f2:](42);
+ pd->g (42);
+ pd->[:g1:] (42);
+ pd->[:g2:] (42);
+ }
+};
+
+struct D2 : C {
+ void mfn (D1 *pd)
+ {
+ auto p = &pd->[: ^^C::val :];
+ auto q = &pd->C::val;
+
+ constexpr auto rg = ^^C::g;
+ pd->[:rg:] (42);
+ constexpr auto rf = ^^C::f;
+ pd->template [:rf:] (42);
+
+ pd->f (42);
+ pd->template [:f1:](42);
+ pd->template [:f2:](42);
+ pd->g (42);
+ pd->[:g1:] (42);
+ pd->[:g2:] (42);
+ }
+};