diff mbox

[3/6] scalar-storage-order merge: C++ front-end

Message ID 5762968.ORykunbcxE@polaris
State New
Headers show

Commit Message

Eric Botcazou June 16, 2015, 8:57 a.m. UTC
This is the C++ front-end part, probably incomplete but passes the testsuite.

cp/
	* class.c (finish_struct_1): If structure has reverse scalar storage
	order, rewrite the type of array fields with scalar component.
	* semantics.c (reduced_constant_expression_p) <CONSTRUCTOR>: Deal with
	TYPE_REVERSE_STORAGE_ORDER.
	* typeck.c (structural_comptypes): Return false if two aggregate types
	have different scalar storage order.
	(cp_build_addr_expr_1) <case COMPONENT_REF>: New case.  Issue the error
	for bit-fields here and not later.
	<case ARRAY_REF>: Issue error and warning for reverse scalar storage
	order.
	* typeck2.c (split_nonconstant_init_1) <RECORD_TYPE>: Deal with
	TYPE_REVERSE_STORAGE_ORDER.

 typeck.c    |   44 +++++++++++++++++++++++++++++++++++++-------
 class.c     |   18 ++++++++++++++++++
 constexpr.c |   21 ++++++++++++++++++---
 typeck2.c   |    8 ++++++--
 4 files changed, 79 insertions(+), 12 deletions(-)
diff mbox

Patch

Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(.../trunk)	(revision 224461)
+++ gcc/cp/typeck.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -1218,6 +1218,9 @@  structural_comptypes (tree t1, tree t2,
     return false;
   if (TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))
     return false;
+  if (AGGREGATE_TYPE_P (t1)
+      && TYPE_REVERSE_STORAGE_ORDER (t1) != TYPE_REVERSE_STORAGE_ORDER (t2))
+    return false;
 
   /* Allow for two different type nodes which have essentially the same
      definition.  Note that we already checked for equality of the type
@@ -5551,6 +5554,40 @@  cp_build_addr_expr_1 (tree arg, bool str
 	}
       break;
 
+    case COMPONENT_REF:
+      if (BASELINK_P (TREE_OPERAND (arg, 1)))
+	break;
+
+      if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
+	{
+	  if (complain & tf_error)
+	    error ("attempt to take address of bit-field structure member %qD",
+		   TREE_OPERAND (arg, 1));
+	  return error_mark_node;
+	}
+      /* Fall through.  */
+
+    case ARRAY_REF:
+      if (TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (TREE_OPERAND (arg, 0))))
+	{
+	  if (!AGGREGATE_TYPE_P (TREE_TYPE (arg)))
+	    {
+	      if (complain & tf_error)
+		error ("attempt to take address of scalar with reverse "
+		       "storage order");
+	      return error_mark_node;
+	    }
+
+	   if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE
+	       && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (arg)))
+	    {
+	      if (complain & tf_warning)
+		warning (OPT_Wscalar_storage_order, "address of array with "
+			 "reverse scalar storage order requested");
+	    }
+	}
+      break;
+
     case BASELINK:
       arg = BASELINK_FUNCTIONS (arg);
       /* Fall through.  */
@@ -5614,13 +5651,6 @@  cp_build_addr_expr_1 (tree arg, bool str
 	val = build2 (COMPOUND_EXPR, TREE_TYPE (val),
 		      TREE_OPERAND (arg, 0), val);
     }
-  else if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
-    {
-      if (complain & tf_error)
-	error ("attempt to take address of bit-field structure member %qD",
-	       TREE_OPERAND (arg, 1));
-      return error_mark_node;
-    }
   else
     {
       tree object = TREE_OPERAND (arg, 0);
Index: gcc/cp/class.c
===================================================================
--- gcc/cp/class.c	(.../trunk)	(revision 224461)
+++ gcc/cp/class.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -6664,6 +6664,24 @@  finish_struct_1 (tree t)
         && TREE_TYPE (x) != error_mark_node
 	&& same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (x)), t))
       DECL_MODE (x) = TYPE_MODE (t);
+    else if (TYPE_REVERSE_STORAGE_ORDER (t)
+	     && TREE_CODE (x) == FIELD_DECL
+	     && TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE)
+      {
+	tree ftype = TREE_TYPE (x);
+	do
+	  ftype = TREE_TYPE (ftype);
+	while (TREE_CODE (ftype) == ARRAY_TYPE);
+	if (!RECORD_OR_UNION_TYPE_P (ftype))
+	  {
+	    tree *ftypep = &TREE_TYPE (x);
+	    do {
+	      *ftypep = build_distinct_type_copy (*ftypep);
+	      TYPE_REVERSE_STORAGE_ORDER (*ftypep) = 1;
+	      ftypep = &TREE_TYPE (*ftypep);
+	    } while (TREE_CODE (*ftypep) == ARRAY_TYPE);
+	  }
+      }
 
   /* Done with FIELDS...now decide whether to sort these for
      faster lookups later.
Index: gcc/cp/constexpr.c
===================================================================
--- gcc/cp/constexpr.c	(.../trunk)	(revision 224461)
+++ gcc/cp/constexpr.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -1438,10 +1438,25 @@  reduced_constant_expression_p (tree t)
 
     case CONSTRUCTOR:
       /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR.  */
-      tree elt; unsigned HOST_WIDE_INT idx;
+      tree elt, reloc; unsigned HOST_WIDE_INT idx;
       FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), idx, elt)
-	if (!reduced_constant_expression_p (elt))
-	  return false;
+	switch (TREE_CODE (elt))
+	  {
+	  case PTRMEM_CST:
+	    break;
+	  case CONSTRUCTOR:
+	    if (!reduced_constant_expression_p (elt))
+	      return false;
+	    break;
+	  default:
+	    if (!(reloc = initializer_constant_valid_p (elt, TREE_TYPE (elt)))
+	        /* An absolute value is required with reverse SSO.  */
+		|| (reloc != null_pointer_node
+		    && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (t))
+		    && !AGGREGATE_TYPE_P (TREE_TYPE (elt))))
+	      return false;
+	    break;
+	  }
       return true;
 
     default:
Index: gcc/cp/typeck2.c
===================================================================
--- gcc/cp/typeck2.c	(.../trunk)	(revision 224461)
+++ gcc/cp/typeck2.c	(.../branches/scalar-storage-order)	(revision 224467)
@@ -594,7 +594,7 @@  static bool
 split_nonconstant_init_1 (tree dest, tree init)
 {
   unsigned HOST_WIDE_INT idx;
-  tree field_index, value;
+  tree field_index, value, reloc;
   tree type = TREE_TYPE (dest);
   tree inner_type = NULL;
   bool array_type_p = false;
@@ -650,7 +650,11 @@  split_nonconstant_init_1 (tree dest, tre
 		CONSTRUCTOR_ELTS (init)->ordered_remove (idx--);
 	      num_split_elts++;
 	    }
-	  else if (!initializer_constant_valid_p (value, inner_type))
+	  else if (!(reloc = initializer_constant_valid_p (value, inner_type))
+		   /* An absolute value is required with reverse SSO.  */
+		   || (reloc != null_pointer_node
+		       && TYPE_REVERSE_STORAGE_ORDER (type)
+		       && !AGGREGATE_TYPE_P (inner_type)))
 	    {
 	      tree code;
 	      tree sub;