diff mbox

[Ada] Relax alignment constraint for tagged types on x86

Message ID 3196271.3PfmUTRSHG@polaris
State New
Headers show

Commit Message

Eric Botcazou May 15, 2017, 8 a.m. UTC
This partially relaxes alignment constraint for tagged types on x86 and, more 
generally, architectures that do not require strict alignment for memory 
accesses, for historical reasons: the compiler now accepts size clauses on 
record type extensions that effectively lower the alignment of the type, if 
there is also a representation clause on the type.

Tested on x86_64-suse-linux, applied on the mainline.


2017-05-15  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Type>: Whenthere
	is a representation clause on an extension, propagate the alignment of
	the parent type only if the platform requires strict alignment.
diff mbox

Patch

Index: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c	(revision 247951)
+++ gcc-interface/decl.c	(working copy)
@@ -204,6 +204,7 @@  static tree elaborate_expression_2 (tree
 static tree elaborate_reference (tree, Entity_Id, bool, tree *);
 static tree gnat_to_gnu_component_type (Entity_Id, bool, bool);
 static tree gnat_to_gnu_subprog_type (Entity_Id, bool, bool, tree *);
+static int adjust_packed (tree, tree, int);
 static tree gnat_to_gnu_field (Entity_Id, tree, int, bool, bool);
 static tree gnu_ext_name_for_subprog (Entity_Id, tree);
 static tree change_qualified_type (tree, int);
@@ -3094,6 +3095,7 @@  gnat_to_gnu_entity (Entity_Id gnat_entit
 	    Entity_Id gnat_parent = Parent_Subtype (gnat_entity);
 	    tree gnu_dummy_parent_type = make_node (RECORD_TYPE);
 	    tree gnu_parent;
+	    int parent_packed = 0;
 
 	    /* A major complexity here is that the parent subtype will
 	       reference our discriminants in its Stored_Constraint list.
@@ -3172,7 +3174,17 @@  gnat_to_gnu_entity (Entity_Id gnat_entit
 	       be created with a component clause below, then we need
 	       to apply the same adjustment as in gnat_to_gnu_field.  */
 	    if (has_rep && TYPE_ALIGN (gnu_type) < TYPE_ALIGN (gnu_parent))
-	      SET_TYPE_ALIGN (gnu_type, TYPE_ALIGN (gnu_parent));
+	      {
+		/* ??? For historical reasons, we do it on strict-alignment
+		   platforms only, where it is really required.  This means
+		   that a confirming representation clause will change the
+		   behavior of the compiler on the other platforms.  */
+		if (STRICT_ALIGNMENT)
+		  SET_TYPE_ALIGN (gnu_type, TYPE_ALIGN (gnu_parent));
+		else
+		  parent_packed
+		    = adjust_packed (gnu_parent, gnu_type, parent_packed);
+	      }
 
 	    /* Finally we fix up both kinds of twisted COMPONENT_REF we have
 	       initially built.  The discriminants must reference the fields
@@ -3218,7 +3230,7 @@  gnat_to_gnu_entity (Entity_Id gnat_entit
 				   ? TYPE_SIZE (gnu_parent) : NULL_TREE,
 				   has_rep
 				   ? bitsize_zero_node : NULL_TREE,
-				   0, 1);
+				   parent_packed, 1);
 	    DECL_INTERNAL_P (gnu_field) = 1;
 	    TREE_OPERAND (gnu_get_parent, 1) = gnu_field;
 	    TYPE_FIELDS (gnu_type) = gnu_field;