On Wed, Mar 04, 2026 at 09:26:32PM +0000, Boris Staletic wrote:
> On Wednesday, March 4th, 2026 at 8:29 PM, Jakub Jelinek <[email protected]> 
> wrote:
> 
> > On Wed, Mar 04, 2026 at 03:21:26PM -0500, Jason Merrill wrote:
> > > On 3/4/26 2:35 PM, Boris Staletic wrote:
> > > > Bootstrapped and tested on tested on x86_64-pc-linux-gnu.
> > > > For the patch I did run the entire `make check`.
> > > >
> > > > I don't think the error message is great,
> > > > but I'm not sure how to improve it.
> > > > I did try `%D` to format the scope as well,
> > > > but that fails when the reflected entity has TU scope.
> > >
> > > No need, I think; for decls outside the global namespace printing the
> > > spliced decl will print its scope without needing to repeat it.  But let's
> > > use %q#D instead of %<%D%>, 'q' to add quotes and # to add 
> > > decl-specifiers.
> > > And you might add
> > >
> > >         inform (DECL_SOURCE_LOCATION (decl), "declared here");
> > >
> > > after the error.
> 
> Done.
> 
> > 
> > But in that case also
> >     auto_diagnostic_group d;
> 
> Done.
> 
> > to group error and inform together.
> > 
> >     Jakub
> > 
> > 
> 
> Here's the v2.
> -- >8 --
> We have to allow splicing "regular" variables
> (i.e. VAR_P (name) == true), because of static data members.
> The rest of the finish_class_member_access_expr() assumes that,
> if there's a scope, it is of a class type (i.e. `CLASS_TYPE_P (scope)`).
> 
> For that reason, checking that `CLASS_TYPE_P (scope)` holds (and erroring
> otherwise), is necessary.
> 
> Signed-off-by: Boris Staletic <[email protected]>
> 
>       PR c++/123726
> 
> gcc/cp/ChangeLog:
> 
>       * typeck.cc: (finish_class_member_access_expr): Check if

Extra ':' after typeck.cc.

>       the scope of the spliced entity in a member access expression
>       is of a class type.
> 
> gcc/testsuite/ChangeLog:
> 
>       * g++.dg/reflect/member21.C: New test.
> ---
>  gcc/cp/typeck.cc                        | 14 +++++++++++++-
>  gcc/testsuite/g++.dg/reflect/member21.C | 13 +++++++++++++
>  2 files changed, 26 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/g++.dg/reflect/member21.C
> 
> diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
> index 79eb3b5ba2..afe8a1ddf6 100644
> --- a/gcc/cp/typeck.cc
> +++ b/gcc/cp/typeck.cc
> @@ -3600,7 +3600,19 @@ finish_class_member_access_expr (cp_expr object, tree 
> name, bool template_p,
>                  || TREE_CODE (name) == CONST_DECL
>                  || TREE_CODE (name) == FUNCTION_DECL
>                  || DECL_FUNCTION_TEMPLATE_P (OVL_FIRST (name))))
> -     scope = context_for_name_lookup (OVL_FIRST (name));
> +     {
> +       scope = context_for_name_lookup (OVL_FIRST (name));
> +       if (!CLASS_TYPE_P (scope))
> +         {
> +           auto_diagnostic_group d;

I think I'd move this auto_diagnostic_group into the following block.

> +           if (complain & tf_error)
> +             {
> +               error ("%q#D is not a member of %qT", name, object_type);
> +               inform (DECL_SOURCE_LOCATION (name), "declared here");
> +             }
> +           return error_mark_node;
> +         }
> +     }
>  
>        if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
>       {
> diff --git a/gcc/testsuite/g++.dg/reflect/member21.C 
> b/gcc/testsuite/g++.dg/reflect/member21.C
> new file mode 100644
> index 0000000000..2b6222ec1a
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/reflect/member21.C
> @@ -0,0 +1,13 @@

Add
// PR c++/123726

Otherwise I'm OK with the patch, thanks!

> +// { dg-do compile { target c++26 } }
> +// { dg-additional-options "-freflection" }
> +
> +struct S {};
> +int x;
> +void f() {}
> +
> +int main() {
> +  S s;
> +  s.[:^^x:];         // { dg-error "not a member of .S." }
> +  s.[:^^s:];         // { dg-error "not a member of .S." }
> +  s.[:^^f:];         // { dg-error "not a member of .S." }
> +}
> -- 
> 2.51.1
> 

Marek

Reply via email to