@@ -1008,6 +1008,10 @@ extern bool must_pass_by_ref (tree gnu_type);
/* Return the size of the FP mode with precision PREC. */
extern int fp_prec_to_size (int prec);
+/* Return the default alignment of a FIELD of TYPE declared in a record or
+ union type as specified by the ABI of the target architecture. */
+extern unsigned int default_field_alignment (tree field, tree type);
+
/* Return the precision of the FP mode with size SIZE. */
extern int fp_size_to_prec (int size);
@@ -28,6 +28,7 @@
#include "coretypes.h"
#include "target.h"
#include "tree.h"
+#include "tm_p.h"
#include "diagnostic.h"
#include "opts.h"
#include "alias.h"
@@ -1129,6 +1130,26 @@ must_pass_by_ref (tree gnu_type)
&& TREE_CODE (TYPE_SIZE_UNIT (gnu_type)) != INTEGER_CST));
}
+/* Return the default alignment of a FIELD of TYPE declared in a record or
+ union type as specified by the ABI of the target architecture. */
+
+unsigned int
+default_field_alignment (tree ARG_UNUSED (field), tree type)
+{
+ /* This is modeled on layout_decl. */
+ unsigned int align = TYPE_ALIGN (type);
+
+#ifdef BIGGEST_FIELD_ALIGNMENT
+ align = MIN (align, (unsigned int) BIGGEST_FIELD_ALIGNMENT);
+#endif
+
+#ifdef ADJUST_FIELD_ALIGN
+ align = ADJUST_FIELD_ALIGN (field, type, align);
+#endif
+
+ return align;
+}
+
/* This function is called by the front-end to enumerate all the supported
modes for the machine, as well as some predefined C types. F is a function
which is called back with the parameters as listed below, first a string,
@@ -10291,23 +10291,13 @@ addressable_p (tree gnu_expr, tree gnu_type)
/* Even with DECL_BIT_FIELD cleared, we have to ensure that
the field is sufficiently aligned, in case it is subject
to a pragma Component_Alignment. But we don't need to
- check the alignment of the containing record, as it is
- guaranteed to be not smaller than that of its most
- aligned field that is not a bit-field. */
- && (DECL_ALIGN (TREE_OPERAND (gnu_expr, 1))
- >= TYPE_ALIGN (TREE_TYPE (gnu_expr))
-#ifdef TARGET_ALIGN_DOUBLE
- /* Cope with the misalignment of doubles in records for
- ancient 32-bit ABIs like that of x86/Linux. */
- || (DECL_ALIGN (TREE_OPERAND (gnu_expr, 1)) == 32
- && TYPE_ALIGN (TREE_TYPE (gnu_expr)) == 64
- && !TARGET_ALIGN_DOUBLE
-#ifdef TARGET_64BIT
- && !TARGET_64BIT
-#endif
- )
-#endif
- ))
+ check the alignment of the containing record, since it
+ is guaranteed to be not smaller than that of its most
+ aligned field that is not a bit-field. However, we need
+ to cope with quirks of ABIs that may misalign fields. */
+ && DECL_ALIGN (TREE_OPERAND (gnu_expr, 1))
+ >= default_field_alignment (TREE_OPERAND (gnu_expr, 1),
+ TREE_TYPE (gnu_expr)))
/* The field of a padding record is always addressable. */
|| TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (gnu_expr, 0))))
&& addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE));
@@ -2220,7 +2220,7 @@ finish_record_type (tree record_type, tree field_list, int rep_level,
if (DECL_BIT_FIELD (field)
&& operand_equal_p (this_size, TYPE_SIZE (type), 0))
{
- const unsigned int align = TYPE_ALIGN (type);
+ const unsigned int align = default_field_alignment (field, type);
/* In the general case, type alignment is required. */
if (value_factor_p (pos, align))
From: Eric Botcazou <ebotcazou@adacore.com> This factors out the interface to the low-level field layout machinery. gcc/ada/ * gcc-interface/gigi.h (default_field_alignment): New function. * gcc-interface/misc.cc: Include tm_p header file. (default_field_alignment): New function. * gcc-interface/trans.cc (addressable_p) <COMPONENT_REF>: Replace previous alignment klduge with call to default_field_alignment. * gcc-interface/utils.cc (finish_record_type): Likewise for the alignment based on which DECL_BIT_FIELD should be cleared. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/gcc-interface/gigi.h | 4 ++++ gcc/ada/gcc-interface/misc.cc | 21 +++++++++++++++++++++ gcc/ada/gcc-interface/trans.cc | 24 +++++++----------------- gcc/ada/gcc-interface/utils.cc | 2 +- 4 files changed, 33 insertions(+), 18 deletions(-)