On Tue, Jun 24, 2025 at 08:25:33PM +0200, Jakub Jelinek wrote: > > > know enough about dynamic_cast and cxx_eval_dynamic_cast_fn > > > to figure out what needs to change there. It is hint -2 that > > > fails, not hint -1. > > > > Yes, this is a -2 case because C does not derive from B. > > > > How does cxx_eval_dynamic_cast_fn fail in this case? From looking at the > > function it seems like it ought to work. > > I'll study it in detail tomorrow.
Actually, I see the reason now. get_component_path is called with a.D.2692, A, NULL where a.D.2692 has B type. And the reason why it fails is 2538 /* We need to check that the component we're accessing is in fact 2539 accessible. */ 2540 if (TREE_PRIVATE (TREE_OPERAND (path, 1)) 2541 || TREE_PROTECTED (TREE_OPERAND (path, 1))) 2542 return error_mark_node; The D.2692 FIELD_DECL has been created by build_base_field_1 called from build_base_field from layout_virtual_bases and that one calls it with 6753 if (!BINFO_PRIMARY_P (vbase)) 6754 { 6755 /* This virtual base is not a primary base of any class in the 6756 hierarchy, so we have to add space for it. */ 6757 next_field = build_base_field (rli, vbase, 6758 access_private_node, 6759 offsets, next_field); 6760 } access_private_node forces TREE_PRIVATE on the FIELD_DECL and so it doesn't reflect whether the base in question was private/protected or public. struct A has also D.2689 FIELD_DECL with C type and that one is the primary base, neither TREE_PRIVATE nor TREE_PROTECTED. Jakub