On Mon, Mar 30, 2026 at 12:52 PM Jakub Jelinek <[email protected]> wrote:

> On Mon, Mar 30, 2026 at 10:26:45AM +0200, Tomasz Kaminski wrote:
> > I would like to see tests of the following:
> > namespace q {
> >       int foo();
> >       int bar();
> >
> > };
> >
> > [: (current_namespace() == ^^::) : ^^int : ^boo :]
> >  q::foo() {}
> >
> > auto q::bar()
> > -> [: (current_namespace() == ^^q) : ^^int : ^boo :]
> >  {}
> >
> > struct X {
> >   struct Y {
> >     int foo();
> >     int bar();
> >   }
> > };
> >
> >
> > [: (current_class() == ^^X) : ^^int : ^boo :]
> >  X::Y:::foo() {}
> >
> > auto X::Y::bar()
> > -> [: (current_class() == ^^Y) : ^^int : ^boo :]
> >  {}
> >
> > And some more test below.
>
> So, I've tried to add the tests, tweaked syntax here and there.
> The
> typename [: current_class () == ^^X ? ^^int : ^^:: :]
> X::Y:::foo ()
> {
>   return 0;
> }
> test part fails, current_class () throws there because there
> is no current class, are you sure that is not the desired behavior?
>
Ah, yes, you are right. I was trying to use nested class to put
defintion at class context, but I do not think that would work.


>
> 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.


>
> > Could you add a test that includes the following?
> > +struct W : T {}
> > +{
> > +  info w = current_function ();
> > +};
> >
> > void bar() {
> > W w;
> > w.t = is_constructor (w.t) && parent_of (w.t) == ^^T;
> > w.w = is_constructor (w.t) && parent_of (w.t) == ^^W;
> > W wb{};
> > w.t = ^^bar;
> > w.t = ^^bar;
> > }
>
> I've added that, but have no idea what you actually meant.
> w.t and w.w are std::meta::info members, so assigning them
> bool result?

I have shortened syntax, to much, I will describe the intent of the check
below. Both of them were meant to be static asserts.


>   If you meant static_assert, then why is the
> condition the same except ^^W vs. ^^T at the end and w would
> need to be constexpr.

My intent here was to test, if  for default-initialzied variable we call
constructors, so if we do W(), then W().t will correspond to default
constructor of T, and W().w to default constructor of W.

However, if we use brace initialization W{}, then the members correspond
to the location of the expressions, so both W{}.t and W{}.w are representing
enclosing function.



>   wb is not used and what is the w.t == ^^bar;
> testing?
>
> > > --- gcc/testsuite/g++.dg/reflect/current_class1.C.jj    2026-03-27
> > > 16:15:47.965107295 +0100
> > > +++ gcc/testsuite/g++.dg/reflect/current_class1.C       2026-03-27
> > > 17:14:36.688766585 +0100
> > > @@ -0,0 +1,70 @@
> > > +// { dg-do compile { target c++26 } }
> > > +// { dg-additional-options "-freflection" }
> > > +// Test std::meta::current_class.
> > >
> > For current_class, I think there is a subtle difference for functions
> > defined out of line:
> > Return // <-
>
> So would you like some further tests or do you think some test is wrong?
>
> Incremental diff:
>
> --- gcc/testsuite/g++.dg/reflect/current_function1.C    2026-03-27
> 16:38:06.301962448 +0100
> +++ gcc/testsuite/g++.dg/reflect/current_function1.C    2026-03-30
> 12:34:57.741967209 +0200
> @@ -38,6 +38,11 @@
>    info v = current_function ();
>  };
>
> +struct W : T
> +{
> +  info w = current_function ();
> +};
> +
>  void
>  bar ()
>  {
> @@ -45,6 +50,7 @@
>    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 @@
>  }
>
>  static_assert (baz ());
> +
> +consteval void
> +fred ()
> +{
> +  W w;
> +//  static_assert (is_constructor (w.t) && parent_of (w.t) == ^^T);
> +//  static_assert (is_constructor (w.t) && parent_of (w.t) == ^^W);
> +  W wb {};
> +  w.t = ^^fred;
> +  w.t = ^^fred;
> +}
> --- gcc/testsuite/g++.dg/reflect/current_class1.C       2026-03-27
> 17:14:36.688766585 +0100
> +++ gcc/testsuite/g++.dg/reflect/current_class1.C       2026-03-30
> 12:38:53.809949829 +0200
> @@ -68,3 +68,23 @@
>      static_assert (parent_of (current_class ()) == ^^bar);
>    };
>  }
> +
> +struct X {
> +  struct Y {
> +    int foo ();
> +    int bar ();
> +  };
> +};
> +
> +typename [: current_class () == ^^X ? ^^int : ^^:: :]
> +X::Y:::foo ()
> +{
> +  return 0;
> +}
> +
> +auto
> +X::Y::bar ()
> +-> typename [: current_class () == ^^Y ? ^^int : ^^:: :]
> +{
> +  return 0;
> +}
> --- gcc/testsuite/g++.dg/reflect/current_namespace1.C   2026-03-27
> 16:38:23.647675541 +0100
> +++ gcc/testsuite/g++.dg/reflect/current_namespace1.C   2026-03-30
> 12:39:23.662441717 +0200
> @@ -92,2 +92,17 @@
>    }
> +
> +  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