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


Reply via email to