@@ -10294,8 +10294,20 @@ addressable_p (tree gnu_expr, tree gnu_type)
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)))
+ && (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
+ ))
/* 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));
From: Eric Botcazou <ebotcazou@adacore.com> Some ancient 32-bit ABIs, most notably that of x86/Linux, misalign double scalars in record types, so comparing DECL_ALIGN with TYPE_ALIGN directly may give the wrong answer for them. gcc/ada/ * gcc-interface/trans.cc (addressable_p) <COMPONENT_REF>: Add kludge to cope with ancient 32-bit ABIs. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/gcc-interface/trans.cc | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)