This is the C++ front-end part, probably incomplete but passes the testsuite.
cp/
* class.c: Add c-family/c-pragma.h.
(finish_struct_1): If structure has reverse scalar storage order,
rewrite the type of array fields with scalar component. Call
maybe_apply_pragma_scalar_storage_order on entry.
* constexpr.c (reduced_constant_expression_p): Unfold recursion and
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>: Adjust call to
initializer_constant_valid_p.
class.c | 24 +++++++++++++++++++++++-
constexpr.c | 19 +++++++++++++++++--
typeck.c | 45 ++++++++++++++++++++++++++++++++++++++-------
typeck2.c | 5 ++++-
4 files changed, 82 insertions(+), 11 deletions(-)
--
Eric Botcazou
Index: cp/typeck.c
===================================================================
--- cp/typeck.c (.../trunk/gcc) (revision 228112)
+++ cp/typeck.c (.../branches/scalar-storage-order/gcc) (revision 228133)
@@ -1217,6 +1217,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
@@ -5584,6 +5587,41 @@ 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))
+ && !VECTOR_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. */
@@ -5647,13 +5685,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: cp/class.c
===================================================================
--- cp/class.c (.../trunk/gcc) (revision 228112)
+++ cp/class.c (.../branches/scalar-storage-order/gcc) (revision 228133)
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.
#include "stor-layout.h"
#include "attribs.h"
#include "cp-tree.h"
+#include "c-family/c-pragma.h"
#include "flags.h"
#include "toplev.h"
#include "target.h"
@@ -6625,6 +6626,7 @@ finish_struct_1 (tree t)
}
/* Layout the class itself. */
+ maybe_apply_pragma_scalar_storage_order (t);
layout_class_type (t, &virtuals);
if (CLASSTYPE_AS_BASE (t) != t)
/* We use the base type for trivial assignments, and hence it
@@ -6688,12 +6690,32 @@ finish_struct_1 (tree t)
set_method_tm_attributes (t);
/* Complete the rtl for any static member objects of the type we're
- working on. */
+ working on and rewrite the type of array fields with scalar
+ component if the enclosing type has reverse storage order. */
for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
if (VAR_P (x) && TREE_STATIC (x)
&& 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);
+ tree ctype = strip_array_types (ftype);
+ if (!RECORD_OR_UNION_TYPE_P (ctype) && TYPE_MODE (ctype) != QImode)
+ {
+ tree fmain_type = TYPE_MAIN_VARIANT (ftype);
+ tree *typep = &fmain_type;
+ do {
+ *typep = build_distinct_type_copy (*typep);
+ TYPE_REVERSE_STORAGE_ORDER (*typep) = 1;
+ typep = &TREE_TYPE (*typep);
+ } while (TREE_CODE (*typep) == ARRAY_TYPE);
+ TREE_TYPE (x)
+ = cp_build_qualified_type (fmain_type, TYPE_QUALS (ftype));
+ }
+ }
/* Done with FIELDS...now decide whether to sort these for
faster lookups later.
Index: cp/constexpr.c
===================================================================
--- cp/constexpr.c (.../trunk/gcc) (revision 228112)
+++ cp/constexpr.c (.../branches/scalar-storage-order/gcc) (revision 228133)
@@ -1439,8 +1439,23 @@ reduced_constant_expression_p (tree t)
/* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR. */
tree elt; 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 (!initializer_constant_valid_p (elt,
+ TREE_TYPE (elt),
+ !VECTOR_TYPE_P (TREE_TYPE (t))
+ && TYPE_REVERSE_STORAGE_ORDER
+ (TREE_TYPE (t))))
+ return false;
+ break;
+ }
return true;
default:
Index: cp/typeck2.c
===================================================================
--- cp/typeck2.c (.../trunk/gcc) (revision 228112)
+++ cp/typeck2.c (.../branches/scalar-storage-order/gcc) (revision 228133)
@@ -648,7 +648,10 @@ 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 (!initializer_constant_valid_p (value,
+ inner_type,
+ TYPE_REVERSE_STORAGE_ORDER
+ (type)))
{
tree code;
tree sub;