On 3/30/26 12:03 PM, Jakub Jelinek wrote:
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.
Tested on x86_64-linux, ok for trunk?
OK adjusted for the name change I asked for in the other patch.
2026-03-30 Jakub Jelinek <[email protected]>
* reflect.cc (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.
--- gcc/cp/reflect.cc.jj 2026-03-30 15:43:40.046055479 +0200
+++ gcc/cp/reflect.cc 2026-03-30 16:41:50.496455140 +0200
@@ -6266,6 +6266,9 @@ current_scope (location_t loc, const con
}
if (current_class_type)
scope = current_class_type;
+ /* If we have been pushed into a different namespace, use it. */
+ else if (!vec_safe_is_empty (decl_namespace_list))
+ scope = decl_namespace_list->last ();
else if (current_namespace)
scope = current_namespace;
else
--- gcc/testsuite/g++.dg/reflect/access_context1.C.jj 2026-03-27
10:17:16.113298446 +0100
+++ gcc/testsuite/g++.dg/reflect/access_context1.C 2026-03-30
16:45:48.856419423 +0200
@@ -146,6 +146,8 @@ namespace O
{
return a;
}
+ int bar ();
+ int baz ();
}
consteval bool
@@ -156,6 +158,18 @@ can_do_via (info r)
return true;
}
+typename [: access_context::current ().scope () == ^^:: ? ^^int : ^^:: :]
+O::bar ()
+{
+ return 0;
+}
+
+auto
+O::baz () -> typename [: access_context::current ().scope () == ^^O ? ^^int :
^^:: :]
+{
+ return 0;
+}
+
struct W;
static_assert (can_do_via (^^S));
--- gcc/testsuite/g++.dg/reflect/current_function1.C.jj 2026-03-30
15:43:40.046585352 +0200
+++ gcc/testsuite/g++.dg/reflect/current_function1.C 2026-03-30
16:18:04.186582636 +0200
@@ -38,6 +38,11 @@ struct V : U
info v = current_function ();
};
+struct W : T
+{
+ info w = current_function ();
+};
+
void
bar ()
{
@@ -45,6 +50,7 @@ bar ()
static_assert (foo (^^foo) == ^^foo);
static_assert (foo () == ^^bar);
static_assert (T {}.t == ^^bar);
+ static_assert (is_constructor (T ().t) && parent_of (T ().t) == ^^T);
consteval {
static_assert (current_function () == ^^bar);
consteval {
@@ -74,3 +80,14 @@ baz ()
}
static_assert (baz ());
+
+consteval void
+fred ()
+{
+ constexpr W w;
+ static_assert (is_constructor (w.t) && parent_of (w.t) == ^^T);
+ static_assert (is_constructor (w.w) && parent_of (w.w) == ^^W);
+ constexpr W wb {};
+ static_assert (wb.t == ^^fred);
+ static_assert (wb.w == ^^fred);
+}
--- gcc/testsuite/g++.dg/reflect/current_class1.C.jj 2026-03-30
15:43:40.046798328 +0200
+++ gcc/testsuite/g++.dg/reflect/current_class1.C 2026-03-30
16:22:13.327347979 +0200
@@ -68,3 +68,16 @@ bar ()
static_assert (parent_of (current_class ()) == ^^bar);
};
}
+
+struct X {
+ struct Y {
+ int foo ();
+ };
+};
+
+auto
+X::Y::foo ()
+-> typename [: current_class () == ^^Y ? ^^int : ^^:: :]
+{
+ return 0;
+}
--- gcc/testsuite/g++.dg/reflect/current_class2.C.jj 2026-03-30
15:43:40.046889261 +0200
+++ gcc/testsuite/g++.dg/reflect/current_class2.C 2026-03-30
16:25:32.717970634 +0200
@@ -71,3 +71,15 @@ namespace O
return a; // { dg-error "invalid
initialization of reference of type" }
}
}
+
+struct X {
+ struct Y {
+ int foo ();
+ };
+};
+
+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'" }
+X::Y::foo () // { dg-error "expected unqualified-id
before 'typename'" "" { target *-*-* } .-1 }
+{
+ return 0;
+}
--- gcc/testsuite/g++.dg/reflect/current_namespace1.C.jj 2026-03-30
15:43:40.046986219 +0200
+++ gcc/testsuite/g++.dg/reflect/current_namespace1.C 2026-03-30
16:12:39.851641760 +0200
@@ -90,4 +90,19 @@ namespace Q
{
return a;
}
+
+ int bar ();
+ int baz ();
+}
+
+typename [: current_namespace () == ^^:: ? ^^int : ^^:: :]
+Q::bar ()
+{
+ return 0;
+}
+
+auto
+Q::baz () -> typename [: current_namespace () == ^^Q ? ^^int : ^^:: :]
+{
+ return 0;
}
Jakub