https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124440

--- Comment #2 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Marek Polacek <[email protected]>:

https://gcc.gnu.org/g:8b626332027ad1ff21f33a5b465e02fcab0cbff9

commit r16-8054-g8b626332027ad1ff21f33a5b465e02fcab0cbff9
Author: Marek Polacek <[email protected]>
Date:   Wed Mar 11 13:28:30 2026 -0400

    c++/reflection: class member access with [: T::BASELINK :] [PR124440]

    Let

      struct B { consteval virtual int fn() const { return 1; } };
      struct D : B { consteval int fn() const override { return 2; } };

    and consider

      d.[:^^B::fn:]()  // #1
      d.[:^^B:]::fn()  // #2

    then #1 should yield 2 and #2 should yield 1: #1 doesn't count as
    qualified name lookup and so should be treated as "d.fn()" where
    lookup_vfn_in_binfo in build_over_call finds D::fn.  But #2 is like
    "d.B::fn()" which should prevent a virtual function call and we
    should be calling B::fn.

    We already handle this correctly outside of templates: finish_call_expr
    only checks IDK to see if it should disallow_virtual, but in tsubst_expr
    it looks at BASELINK_QUALIFIED_P, which is wrongly set for #1.

    BASELINK_QUALIFIED_P is always set by adjust_result_of_q_name_lookup,
    so cp_parser_postfix_dot_deref_expression should clear it for case #1.
    With this patch, we only set BASELINK_QUALIFIED_P if qualifying_scope
    was not null.

    Unfortunately we can't avoid the adjust_result_ call because then
    lookup_vfn_in_binfo gets a binfo that isn't BINFO_PRIMARY_P and it won't
    find D::fn.  It seems it is necessary to have that adjust_result_ ->
    lookup_base adjustment.

    And then tsubst_expr has to do the same thing for when we have

      d.[:^^T::fn:]()

    where T is a tparm that is substituted with B.

            PR c++/124440

    gcc/cp/ChangeLog:

            * parser.cc (cp_parser_postfix_dot_deref_expression): Pass
            parser->scope to adjust_result_of_qualified_name_lookup even
            when splice_p.  Assign the result of
            adjust_result_of_qualified_name_lookup to name.
            * pt.cc (tsubst_expr): Call adjust_result_of_qualified_name_lookup
            for BASELINKs in splice-expressions.
            * search.cc (adjust_result_of_qualified_name_lookup): Return early
            if decl is not a BASELINK.  If qualifying_scope is null, use decl's
            binfo.  Set BASELINK_QUALIFIED_P only if qualifying_scope wasn't
            null.

    gcc/testsuite/ChangeLog:

            * g++.dg/reflect/member21.C: Uncomment the commented out asserts.

    Reviewed-by: Jason Merrill <[email protected]>

Reply via email to