aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2025-08-05 09:14:44 +0200
committerMarc Poulhiès <dkm@gcc.gnu.org>2025-09-11 11:10:50 +0200
commit88a389ac8664360aaf8b2a628df8da24b678daa8 (patch)
tree2c21b8a355be2fa31fc81fe574cbe10baa7e2f4c
parentc93fe0be50bcf622181b3036c89ebda0a71132d7 (diff)
downloadgcc-88a389ac8664360aaf8b2a628df8da24b678daa8.zip
gcc-88a389ac8664360aaf8b2a628df8da24b678daa8.tar.gz
gcc-88a389ac8664360aaf8b2a628df8da24b678daa8.tar.bz2
ada: Get rid of TYPE_ALIGN_OK flag in gcc-interface
The TYPE_ALIGN_OK flag had originally been a GCC flag tested in the RTL expander and was at some point kicked out of the middle-end to become a pure Gigi flag. But it's only set for tagged types and CW-equivalent types and can be replaced by a explicit predicate without too much work. gcc/ada/ChangeLog: * gcc-interface/ada-tree.h (TYPE_ALIGN_OK): Delete. * gcc-interface/decl.cc (gnat_to_gnu_entity): Do not set it. * gcc-interface/gigi.h (standard_datatypes): Add ADT_tag_name_id. (tag_name_id): New macro. (type_is_tagged_or_cw_equivalent): New inline predicate. * gcc-interface/trans.cc (gigi): Initialize tag_name_id. (gnat_to_gnu) <N_Unchecked_Type_Conversion>: Replace tests on TYPE_ALIGN_OK with calls to type_is_tagged_or_cw_equivalent. (addressable_p): Likewise. * gcc-interface/utils.cc (convert): Likewise. * gcc-interface/utils2.cc (build_binary_op): Likewise.
-rw-r--r--gcc/ada/gcc-interface/ada-tree.h3
-rw-r--r--gcc/ada/gcc-interface/decl.cc8
-rw-r--r--gcc/ada/gcc-interface/gigi.h26
-rw-r--r--gcc/ada/gcc-interface/trans.cc14
-rw-r--r--gcc/ada/gcc-interface/utils.cc3
-rw-r--r--gcc/ada/gcc-interface/utils2.cc6
6 files changed, 41 insertions, 19 deletions
diff --git a/gcc/ada/gcc-interface/ada-tree.h b/gcc/ada/gcc-interface/ada-tree.h
index 205136b..8f930dd 100644
--- a/gcc/ada/gcc-interface/ada-tree.h
+++ b/gcc/ada/gcc-interface/ada-tree.h
@@ -184,9 +184,6 @@ do { \
/* True for a dummy type if TYPE appears in a profile. */
#define TYPE_DUMMY_IN_PROFILE_P(NODE) TYPE_LANG_FLAG_6 (NODE)
-/* True if objects of this type are guaranteed to be properly aligned. */
-#define TYPE_ALIGN_OK(NODE) TYPE_LANG_FLAG_7 (NODE)
-
/* True for types that implement a packed array and for original packed array
types. */
#define TYPE_IMPL_PACKED_ARRAY_P(NODE) \
diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc
index 86cbf5b..771325d 100644
--- a/gcc/ada/gcc-interface/decl.cc
+++ b/gcc/ada/gcc-interface/decl.cc
@@ -4821,14 +4821,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
{
bool align_clause;
- /* Record the property that objects of tagged types are guaranteed to
- be properly aligned. This is necessary because conversions to the
- class-wide type are translated into conversions to the root type,
- which can be less aligned than some of its derived types. */
- if (Is_Tagged_Type (gnat_entity)
- || Is_Class_Wide_Equivalent_Type (gnat_entity))
- TYPE_ALIGN_OK (gnu_type) = 1;
-
/* Record whether the type is passed by reference. */
if (is_by_ref && !VOID_TYPE_P (gnu_type))
TYPE_BY_REFERENCE_P (gnu_type) = 1;
diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h
index 45b1bfd..2533bd4 100644
--- a/gcc/ada/gcc-interface/gigi.h
+++ b/gcc/ada/gcc-interface/gigi.h
@@ -399,6 +399,9 @@ enum standard_datatypes
/* Identifier for the name of the _Parent field in tagged record types. */
ADT_parent_name_id,
+ /* Identifier for the name of the _Tag field in tagged record types. */
+ ADT_tag_name_id,
+
/* Identifier for the name of the Not_Handled_By_Others field. */
ADT_not_handled_by_others_name_id,
@@ -461,6 +464,7 @@ extern GTY(()) tree gnat_raise_decls_ext[(int) LAST_REASON_CODE + 1];
#define mulv128_decl gnat_std_decls[(int) ADT_mulv128_decl]
#define uns_mulv128_decl gnat_std_decls[(int) ADT_uns_mulv128_decl]
#define parent_name_id gnat_std_decls[(int) ADT_parent_name_id]
+#define tag_name_id gnat_std_decls[(int) ADT_tag_name_id]
#define not_handled_by_others_name_id \
gnat_std_decls[(int) ADT_not_handled_by_others_name_id]
#define reraise_zcx_decl gnat_std_decls[(int) ADT_reraise_zcx_decl]
@@ -1124,6 +1128,28 @@ call_is_atomic_load (tree exp)
return BUILT_IN_ATOMIC_LOAD_N <= code && code <= BUILT_IN_ATOMIC_LOAD_16;
}
+/* Return true if TYPE is a tagged type or a CW-equivalent type. */
+
+static inline bool
+type_is_tagged_or_cw_equivalent (tree type)
+{
+ if (!RECORD_OR_UNION_TYPE_P (type))
+ return false;
+
+ tree field = TYPE_FIELDS (type);
+ if (!field)
+ return false;
+
+ /* The tag can be put into the REP part of a record type. */
+ if (DECL_INTERNAL_P (field))
+ return type_is_tagged_or_cw_equivalent (TREE_TYPE (field));
+
+ tree name = DECL_NAME (field);
+
+ /* See Exp_Util.Make_CW_Equivalent_Type for the CW-equivalent case. */
+ return name == tag_name_id || name == parent_name_id;
+}
+
/* Return true if TYPE is padding a self-referential type. */
static inline bool
diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc
index 3c6e87e..e8baa5c 100644
--- a/gcc/ada/gcc-interface/trans.cc
+++ b/gcc/ada/gcc-interface/trans.cc
@@ -512,6 +512,9 @@ gigi (Node_Id gnat_root,
/* Name of the _Parent field in tagged record types. */
parent_name_id = get_identifier (Get_Name_String (Name_uParent));
+ /* Name of the _Tag field in tagged record types. */
+ tag_name_id = get_identifier (Get_Name_String (Name_uTag));
+
/* Name of the Not_Handled_By_Others field in exception record types. */
not_handled_by_others_name_id = get_identifier ("not_handled_by_others");
@@ -7304,7 +7307,12 @@ gnat_to_gnu (Node_Id gnat_node)
tree gnu_obj_type = TREE_TYPE (gnu_result_type);
unsigned int oalign = TYPE_ALIGN (gnu_obj_type);
- if (align != 0 && align < oalign && !TYPE_ALIGN_OK (gnu_obj_type))
+ /* Skip tagged types because conversions to the class-wide type are
+ translated into conversions to the root type, which may be less
+ aligned than some of its derived types. */
+ if (align != 0
+ && align < oalign
+ && !type_is_tagged_or_cw_equivalent (gnu_obj_type))
post_error_ne_tree_2
("??source alignment (^) '< alignment of & (^)",
gnat_node, Designated_Type (Etype (gnat_node)),
@@ -10612,8 +10620,8 @@ addressable_p (tree gnu_expr, tree gnu_type, bool compg)
&& (!STRICT_ALIGNMENT
|| TYPE_ALIGN (type) <= TYPE_ALIGN (inner_type)
|| TYPE_ALIGN (inner_type) >= BIGGEST_ALIGNMENT
- || TYPE_ALIGN_OK (type)
- || TYPE_ALIGN_OK (inner_type))))
+ || type_is_tagged_or_cw_equivalent (type)
+ || type_is_tagged_or_cw_equivalent (inner_type))))
&& addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE,
compg));
}
diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc
index f501915..ccb0752 100644
--- a/gcc/ada/gcc-interface/utils.cc
+++ b/gcc/ada/gcc-interface/utils.cc
@@ -5139,7 +5139,8 @@ convert (tree type, tree expr)
But don't do it if we are just annotating types since tagged types
aren't fully laid out in this mode. */
else if (ecode == RECORD_TYPE && code == RECORD_TYPE
- && TYPE_ALIGN_OK (etype) && TYPE_ALIGN_OK (type)
+ && type_is_tagged_or_cw_equivalent (etype)
+ && type_is_tagged_or_cw_equivalent (type)
&& !type_annotate_only)
{
tree child_etype = etype;
diff --git a/gcc/ada/gcc-interface/utils2.cc b/gcc/ada/gcc-interface/utils2.cc
index 58418ea..b76054c 100644
--- a/gcc/ada/gcc-interface/utils2.cc
+++ b/gcc/ada/gcc-interface/utils2.cc
@@ -1041,9 +1041,7 @@ build_binary_op (enum tree_code op_code, tree result_type,
}
/* If a class-wide type may be involved, force use of the RHS type. */
- if ((TREE_CODE (right_type) == RECORD_TYPE
- || TREE_CODE (right_type) == UNION_TYPE)
- && TYPE_ALIGN_OK (right_type))
+ if (type_is_tagged_or_cw_equivalent (right_type))
operation_type = right_type;
/* If we are copying between padded objects with compatible types, use
@@ -1118,7 +1116,7 @@ build_binary_op (enum tree_code op_code, tree result_type,
== TREE_CODE (operand_type (result))
&& TYPE_MODE (restype)
== TYPE_MODE (operand_type (result))))
- || TYPE_ALIGN_OK (restype))))
+ || type_is_tagged_or_cw_equivalent (restype))))
result = TREE_OPERAND (result, 0);
else if (TREE_CODE (result) == VIEW_CONVERT_EXPR)