Skip to content

Commit eaa6998

Browse files
committed
c++: Fix up access_context::current and current_namespace
On Mon, Mar 30, 2026 at 01:15:07PM +0200, Tomasz Kaminski wrote: > > auto > > Q::baz () -> typename [: current_namespace () == ^^Q ? ^^int : ^^:: :] > > { > > return 0; > > } > > part also fails, there I don't know what's right but possibly it should > > be in Q; in that case it would be a pre-existing bug already for > > std::meta::access_context::current () too. > > > My reading of the standard may be wrong here. I think you're right, but because it is a preexisting bug on access_context, sending this as a separate patch rather than updating the current_* patch. 2026-04-01 Jakub Jelinek <jakub@redhat.com> * reflect.cc (reflect_current_scope): Use decl_namespace_list->last () in preference to current_namespace. * g++.dg/reflect/access_context1.C: Add new tests. * g++.dg/reflect/current_function1.C: Likewise. * g++.dg/reflect/current_class1.C: Likewise. * g++.dg/reflect/current_class2.C: Likewise. * g++.dg/reflect/current_namespace1.C: Likewise. Reviewed-by: Jason Merrill <jason@redhat.com>
1 parent ec5605d commit eaa6998

6 files changed

Lines changed: 74 additions & 0 deletions

File tree

gcc/cp/reflect.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6356,6 +6356,9 @@ reflect_current_scope (location_t loc, const constexpr_ctx *ctx, tree call,
63566356
}
63576357
if (current_class_type)
63586358
scope = current_class_type;
6359+
/* If we have been pushed into a different namespace, use it. */
6360+
else if (!vec_safe_is_empty (decl_namespace_list))
6361+
scope = decl_namespace_list->last ();
63596362
else if (current_namespace)
63606363
scope = current_namespace;
63616364
else

gcc/testsuite/g++.dg/reflect/access_context1.C

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ namespace O
146146
{
147147
return a;
148148
}
149+
int bar ();
150+
int baz ();
149151
}
150152

151153
consteval bool
@@ -156,6 +158,18 @@ can_do_via (info r)
156158
return true;
157159
}
158160

161+
typename [: access_context::current ().scope () == ^^:: ? ^^int : ^^:: :]
162+
O::bar ()
163+
{
164+
return 0;
165+
}
166+
167+
auto
168+
O::baz () -> typename [: access_context::current ().scope () == ^^O ? ^^int : ^^:: :]
169+
{
170+
return 0;
171+
}
172+
159173
struct W;
160174

161175
static_assert (can_do_via (^^S));

gcc/testsuite/g++.dg/reflect/current_class1.C

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,16 @@ bar ()
6868
static_assert (parent_of (current_class ()) == ^^bar);
6969
};
7070
}
71+
72+
struct X {
73+
struct Y {
74+
int foo ();
75+
};
76+
};
77+
78+
auto
79+
X::Y::foo ()
80+
-> typename [: current_class () == ^^Y ? ^^int : ^^:: :]
81+
{
82+
return 0;
83+
}

gcc/testsuite/g++.dg/reflect/current_class2.C

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,15 @@ namespace O
7171
return a; // { dg-error "invalid initialization of reference of type" }
7272
}
7373
}
74+
75+
struct X {
76+
struct Y {
77+
int foo ();
78+
};
79+
};
80+
81+
typename [: current_class () == ^^X ? ^^int : ^^:: :] // { dg-error "uncaught exception of type 'std::meta::exception'; 'what\\\(\\\)': 'current scope does not represent a class nor a member function'" }
82+
X::Y::foo () // { dg-error "expected unqualified-id before 'typename'" "" { target *-*-* } .-1 }
83+
{
84+
return 0;
85+
}

gcc/testsuite/g++.dg/reflect/current_function1.C

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,19 @@ struct V : U
3838
info v = current_function ();
3939
};
4040

41+
struct W : T
42+
{
43+
info w = current_function ();
44+
};
45+
4146
void
4247
bar ()
4348
{
4449
static_assert (current_function () == ^^bar);
4550
static_assert (foo (^^foo) == ^^foo);
4651
static_assert (foo () == ^^bar);
4752
static_assert (T {}.t == ^^bar);
53+
static_assert (is_constructor (T ().t) && parent_of (T ().t) == ^^T);
4854
consteval {
4955
static_assert (current_function () == ^^bar);
5056
consteval {
@@ -74,3 +80,14 @@ baz ()
7480
}
7581

7682
static_assert (baz ());
83+
84+
consteval void
85+
fred ()
86+
{
87+
constexpr W w;
88+
static_assert (is_constructor (w.t) && parent_of (w.t) == ^^T);
89+
static_assert (is_constructor (w.w) && parent_of (w.w) == ^^W);
90+
constexpr W wb {};
91+
static_assert (wb.t == ^^fred);
92+
static_assert (wb.w == ^^fred);
93+
}

gcc/testsuite/g++.dg/reflect/current_namespace1.C

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,19 @@ namespace Q
9090
{
9191
return a;
9292
}
93+
94+
int bar ();
95+
int baz ();
96+
}
97+
98+
typename [: current_namespace () == ^^:: ? ^^int : ^^:: :]
99+
Q::bar ()
100+
{
101+
return 0;
102+
}
103+
104+
auto
105+
Q::baz () -> typename [: current_namespace () == ^^Q ? ^^int : ^^:: :]
106+
{
107+
return 0;
93108
}

0 commit comments

Comments
 (0)