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

--- Comment #23 from Eric Botcazou <ebotcazou at gcc dot gnu.org> ---
> I'm not exactly sure how so.  For constant sizes you could use a
> BIT_FIELD_REF, but for variable sizes there's no good alternative
> (a V_C_E to a fake union plus component-ref maybe?).  That said,
> the upcasting is always to a same or smaller size type, it'll never
> be a "paradoxical subreg", right?

Yes, upcasting always shrinks the types and derived (tagged) types contain an
explicit _Parent component of the parent type in Ada, so you can always build a
COMPONENT_REF of it if the size is the same (or smaller).

This at least passes ACATS and gnat.dg:

diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc
index f501915e82f..24a559c0c86 100644
--- a/gcc/ada/gcc-interface/utils.cc
+++ b/gcc/ada/gcc-interface/utils.cc
@@ -5145,8 +5145,13 @@ convert (tree type, tree expr)
       tree child_etype = etype;
       do {
        tree field = TYPE_FIELDS (child_etype);
-       if (DECL_NAME (field) == parent_name_id && TREE_TYPE (field) == type)
-         return build_component_ref (expr, field, false);
+       if (DECL_NAME (field) == parent_name_id)
+         {
+           if (TREE_TYPE (field) == type)
+             return build_component_ref (expr, field, false);
+           if (DECL_SIZE (field) == TYPE_SIZE (type))
+             return convert (type, build_component_ref (expr, field, false));
+         }
        child_etype = TREE_TYPE (field);
       } while (TREE_CODE (child_etype) == RECORD_TYPE);
     }

Reply via email to