diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dc3af2dca97..a62f254d1c8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2000-06-13 Jakub Jelinek + + * tree.h (TYPE_USER_ALIGN, DECL_USER_ALIGN): Define. + (struct tree_type, struct tree_decl): Add user_align member. + * stor-layout.c (layout_decl): Set DECL_USER_ALIGN. + (place_union_field): If BIGGEST_FIELD_ALIGNMENT is defined + and DECL_USER_ALIGN 0, cap alignment to this value. + (place_field): Likewise. + (finalize_type_size): Set TYPE_USER_ALIGN. + (layout_type): Likewise. + (initialize_sizetypes): Likewise. + * c-common.c (decl_attributes): Set TYPE_USER_ALIGN resp. + DECL_USER_ALIGN to 1. + * c-decl.c (duplicate_decls): Set DECL_USER_ALIGN. + (xfer_tag): Set TYPE_USER_ALIGN. + (finish_struct): Set DECL_USER_ALIGN resp. TYPE_USER_ALIGN. + (finish_enum): Likewise. + * stmt.c (expand_decl): Set DECL_USER_ALIGN. + (expand_anon_union_decl): Likewise. + * tree.c (make_node): Set DECL_USER_ALIGN resp. TYPE_USER_ALIGN. + (build_index_type): Set TYPE_USER_ALIGN. + (build_range_type): Likewise. + (build_common_tree_nodes_2): Likewise. + * tm.texi (BIGGEST_FIELD_ALIGNMENT): Document the changed meaning. + 2000-06-13 Andreas Jaeger * configure.in: Use --enable-checking=misc,tree,gc by default if diff --git a/gcc/c-common.c b/gcc/c-common.c index 298afa5f643..445ec0941c4 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -779,13 +779,19 @@ decl_attributes (node, attributes, prefix_attributes) else if (i > HOST_BITS_PER_INT - 2) error ("requested alignment is too large"); else if (is_type) - TYPE_ALIGN (type) = (1 << i) * BITS_PER_UNIT; + { + TYPE_ALIGN (type) = (1 << i) * BITS_PER_UNIT; + TYPE_USER_ALIGN (type) = 1; + } else if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FIELD_DECL) error_with_decl (decl, "alignment may not be specified for `%s'"); else - DECL_ALIGN (decl) = (1 << i) * BITS_PER_UNIT; + { + DECL_ALIGN (decl) = (1 << i) * BITS_PER_UNIT; + DECL_USER_ALIGN (decl) = 1; + } } break; diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 5ee40ba2a5d..cabc4c197e2 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -1805,7 +1805,10 @@ duplicate_decls (newdecl, olddecl, different_binding_level) DECL_MODE (newdecl) = DECL_MODE (olddecl); if (TREE_CODE (olddecl) != FUNCTION_DECL) if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl)) - DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl); + { + DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl); + DECL_USER_ALIGN (newdecl) |= DECL_ALIGN (olddecl); + } } /* Keep the old rtl since we can safely use it. */ @@ -5102,6 +5105,7 @@ xref_tag (code, name) to avoid crashing if it does not get defined. */ TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node); TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node); + TYPE_USER_ALIGN (ref) = 0; TREE_UNSIGNED (ref) = 1; TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node); TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node); @@ -5328,8 +5332,11 @@ finish_struct (t, fieldlist, attributes) #endif #ifdef PCC_BITFIELD_TYPE_MATTERS if (PCC_BITFIELD_TYPE_MATTERS) - DECL_ALIGN (x) = MAX (DECL_ALIGN (x), - TYPE_ALIGN (TREE_TYPE (x))); + { + DECL_ALIGN (x) = MAX (DECL_ALIGN (x), + TYPE_ALIGN (TREE_TYPE (x))); + DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x)); + } #endif } } @@ -5343,6 +5350,8 @@ finish_struct (t, fieldlist, attributes) /* Non-bit-fields are aligned for their type, except packed fields which require only BITS_PER_UNIT alignment. */ DECL_ALIGN (x) = MAX (DECL_ALIGN (x), min_align); + if (! DECL_PACKED (x)) + DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x)); } DECL_INITIAL (x) = 0; @@ -5400,6 +5409,7 @@ finish_struct (t, fieldlist, attributes) TYPE_FIELDS (x) = TYPE_FIELDS (t); TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t); TYPE_ALIGN (x) = TYPE_ALIGN (t); + TYPE_USER_ALIGN (x) = TYPE_USER_ALIGN (t); } /* If this was supposed to be a transparent union, but we can't @@ -5584,6 +5594,7 @@ finish_enum (enumtype, values, attributes) DECL_SIZE (enu) = TYPE_SIZE (enumtype); DECL_SIZE_UNIT (enu) = TYPE_SIZE_UNIT (enumtype); DECL_ALIGN (enu) = TYPE_ALIGN (enumtype); + DECL_USER_ALIGN (enu) = TYPE_USER_ALIGN (enumtype); DECL_MODE (enu) = TYPE_MODE (enumtype); DECL_INITIAL (enu) = convert (enumtype, DECL_INITIAL (enu)); @@ -5607,6 +5618,7 @@ finish_enum (enumtype, values, attributes) TYPE_MODE (tem) = TYPE_MODE (enumtype); TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype); TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype); + TYPE_USER_ALIGN (tem) = TYPE_USER_ALIGN (enumtype); TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype); } diff --git a/gcc/ch/ChangeLog b/gcc/ch/ChangeLog index d63d1abdd52..59ab9342336 100644 --- a/gcc/ch/ChangeLog +++ b/gcc/ch/ChangeLog @@ -1,3 +1,11 @@ +2000-06-13 Jakub Jelinek + + * decl.c (init_decl_processing): Set TYPE_USER_ALIGN. + (layout_enum): Set DECL_USER_ALIGN resp. TYPE_USER_ALIGN. + * typeck.c (layout_chill_range_type): Set TYPE_USER_ALIGN. + (apply_chill_field_layout): Set DECL_USER_ALIGN. + (layout_chill_struct_type): Set TYPE_USER_ALIGN. + Tue Jun 13 15:30:46 2000 Maciej W. Rozycki * Make-lang.in (CHILL.install-common): Use $(INSTALL_SCRIPT), not diff --git a/gcc/ch/decl.c b/gcc/ch/decl.c index 45f2656e567..d5fcb1d26aa 100644 --- a/gcc/ch/decl.c +++ b/gcc/ch/decl.c @@ -3447,6 +3447,7 @@ init_decl_processing () /* We are not going to have real types in C with less than byte alignment, so we might as well not have any types that claim to have it. */ TYPE_ALIGN (void_type_node) = BITS_PER_UNIT; + TYPE_USER_ALIGN (void_type_node) = 0; /* This is for wide string constants. */ wchar_type_node = short_unsigned_type_node; @@ -4596,6 +4597,7 @@ layout_enum (enumtype) DECL_SIZE (decl) = TYPE_SIZE (enumtype); DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (enumtype); DECL_ALIGN (decl) = TYPE_ALIGN (enumtype); + DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (enumtype); /* Set the TREE_VALUE to the name, rather than the decl, since that is what the rest of the compiler expects. */ @@ -4612,6 +4614,7 @@ layout_enum (enumtype) TYPE_MODE (tem) = TYPE_MODE (enumtype); TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype); TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype); + TYPE_USER_ALIGN (tem) = TYPE_USER_ALIGN (enumtype); TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype); } diff --git a/gcc/ch/typeck.c b/gcc/ch/typeck.c index 17539602e30..7c4f554e7de 100644 --- a/gcc/ch/typeck.c +++ b/gcc/ch/typeck.c @@ -2725,6 +2725,7 @@ layout_chill_range_type (rangetype, must_be_const) TYPE_SIZE (rangetype) = TYPE_SIZE (type); TYPE_SIZE_UNIT (rangetype) = TYPE_SIZE_UNIT (type); TYPE_ALIGN (rangetype) = TYPE_ALIGN (type); + TYPE_USER_ALIGN (rangetype) = TYPE_USER_ALIGN (type); TREE_UNSIGNED (rangetype) = TREE_UNSIGNED (type); CH_NOVELTY (rangetype) = CH_NOVELTY (type); return rangetype; @@ -3113,7 +3114,10 @@ apply_chill_field_layout (decl, next_struct_offset) DECL_SIZE (decl) = bitsize_int (natural_length); } else - DECL_ALIGN (decl) = BITS_PER_UNIT; + { + DECL_ALIGN (decl) = BITS_PER_UNIT; + DECL_USER_ALIGN (decl) = 0; + } DECL_PACKED (decl) = 1; *next_struct_offset += natural_length; @@ -3351,6 +3355,7 @@ layout_chill_struct_type (t) TYPE_FIELDS (x) = TYPE_FIELDS (t); TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t); TYPE_ALIGN (x) = TYPE_ALIGN (t); + TYPE_USER_ALIGN (x) = TYPE_USER_ALIGN (t); } resume_momentary (old_momentary); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 76bb5ee02da..ff78949a53a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,18 @@ +2000-06-13 Jakub Jelinek + + * class.c (build_secondary_vtable): Set DECL_USER_ALIGN. + (check_bitfield_decl, check_field_decl): Likewise. + (build_vtbl_or_vbase_field, build_base_field): Likewise. + (layout_class_type): Set DECL_USER_ALIGN resp. CLASSTYPE_USER_ALIGN. + * decl.c (record_unknown_type): Set TYPE_USER_ALIGN. + (xfer_tag, finish_enum): Likewise. + * decl2.c (finish_builtin_type): Likewise. + * init.c (init_init_processing): Likewise. + * pt.c (instantiate_class_template): Likewise. + * rtti.c (get_tinfo_decl, synthesize_tinfo_fn): Set DECL_USER_ALIGN. + * cp-tree.h (struct lang_type): Add user_align member. + (CLASSTYPE_USER_ALIGN): Define. + Tue Jun 13 15:48:03 2000 Maciej W. Rozycki * Make-lang.in (c++.install-common): Install g++-cross in diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 4d9d3991e32..5d8390f2b5b 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -984,6 +984,7 @@ build_secondary_vtable (binfo, for_type) new_decl = build_vtable (for_type, name, TREE_TYPE (orig_decl)); DECL_ALIGN (new_decl) = DECL_ALIGN (orig_decl); + DECL_USER_ALIGN (new_decl) = DECL_USER_ALIGN (orig_decl); BINFO_VTABLE (binfo) = pushdecl_top_level (new_decl); #ifdef GATHER_STATISTICS @@ -3225,8 +3226,11 @@ check_bitfield_decl (field) #endif #ifdef PCC_BITFIELD_TYPE_MATTERS if (PCC_BITFIELD_TYPE_MATTERS) - DECL_ALIGN (field) = MAX (DECL_ALIGN (field), - TYPE_ALIGN (type)); + { + DECL_ALIGN (field) = MAX (DECL_ALIGN (field), + TYPE_ALIGN (type)); + DECL_USER_ALIGN (field) |= TYPE_USER_ALIGN (type); + } #endif } } @@ -3236,6 +3240,7 @@ check_bitfield_decl (field) DECL_BIT_FIELD (field) = 0; CLEAR_DECL_C_BIT_FIELD (field); DECL_ALIGN (field) = MAX (DECL_ALIGN (field), TYPE_ALIGN (type)); + DECL_USER_ALIGN (field) |= TYPE_USER_ALIGN (type); } } @@ -3326,6 +3331,8 @@ check_field_decl (field, t, cant_have_const_ctor, (DECL_PACKED (field) ? BITS_PER_UNIT : TYPE_ALIGN (TREE_TYPE (field)))); + if (! DECL_PACKED (field)) + DECL_USER_ALIGN (field) |= TYPE_USER_ALIGN (TREE_TYPE (field)); } /* Check the data members (both static and non-static), class-scoped @@ -3625,6 +3632,7 @@ build_vtbl_or_vbase_field (name, assembler_name, type, class_type, fcontext, DECL_FIELD_CONTEXT (field) = class_type; DECL_FCONTEXT (field) = fcontext; DECL_ALIGN (field) = TYPE_ALIGN (type); + DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (type); /* Return it. */ return field; @@ -3844,6 +3852,7 @@ build_base_field (rli, binfo, empty_p, base_align, v) DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype); DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype); DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype); + DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype); if (! flag_new_abi) { @@ -4800,6 +4809,7 @@ layout_class_type (t, empty_p, vfuns_p, TYPE_SIZE (integer_type)); DECL_SIZE (field) = TYPE_SIZE (integer_type); DECL_ALIGN (field) = TYPE_ALIGN (integer_type); + DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (integer_type); } else padding = NULL_TREE; @@ -4821,6 +4831,7 @@ layout_class_type (t, empty_p, vfuns_p, DECL_BIT_FIELD (padding_field) = 1; DECL_SIZE (padding_field) = padding; DECL_ALIGN (padding_field) = 1; + DECL_USER_ALIGN (padding_field) = 0; layout_nonempty_base_or_field (rli, padding_field, NULL_TREE, v); } } @@ -4897,6 +4908,7 @@ layout_class_type (t, empty_p, vfuns_p, } CLASSTYPE_ALIGN (t) = TYPE_ALIGN (t); + CLASSTYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (t); /* Set the TYPE_DECL for this type to contain the right value for DECL_OFFSET, so that we can use it as part diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 1b65b6a55a4..8fd811573d3 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1395,6 +1395,7 @@ struct lang_type unsigned has_abstract_assign_ref : 1; unsigned non_aggregate : 1; unsigned is_partial_instantiation : 1; + unsigned user_align : 1; /* When adding a flag here, consider whether or not it ought to apply to a template instance if it applies to the template. If @@ -1403,7 +1404,7 @@ struct lang_type /* There are some bits left to fill out a 32-bit word. Keep track of this by updating the size of this bitfield whenever you add or remove a flag. */ - unsigned dummy : 9; + unsigned dummy : 8; int vsize; int vfield_parent; @@ -1637,6 +1638,7 @@ struct lang_type #define CLASSTYPE_SIZE(NODE) (TYPE_LANG_SPECIFIC(NODE)->size) #define CLASSTYPE_SIZE_UNIT(NODE) (TYPE_LANG_SPECIFIC(NODE)->size_unit) #define CLASSTYPE_ALIGN(NODE) (TYPE_LANG_SPECIFIC(NODE)->align) +#define CLASSTYPE_USER_ALIGN(NODE) (TYPE_LANG_SPECIFIC(NODE)->user_align) /* The alignment of NODE, without its virtual bases, in bytes. */ #define CLASSTYPE_ALIGN_UNIT(NODE) \ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index d14b824f2ec..93e6c3f40de 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6200,6 +6200,7 @@ record_unknown_type (type, name) TYPE_DECL_SUPPRESS_DEBUG (decl) = 1; TYPE_SIZE (type) = TYPE_SIZE (void_type_node); TYPE_ALIGN (type) = 1; + TYPE_USER_ALIGN (type) = 0; TYPE_MODE (type) = TYPE_MODE (void_type_node); } @@ -12884,6 +12885,7 @@ xref_tag (code_type_node, name, globalize) to avoid crashing if it does not get defined. */ TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node); TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node); + TYPE_USER_ALIGN (ref) = 0; TREE_UNSIGNED (ref) = 1; TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node); TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node); @@ -13297,6 +13299,7 @@ finish_enum (enumtype) TYPE_MODE (tem) = TYPE_MODE (enumtype); TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype); TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype); + TYPE_USER_ALIGN (tem) = TYPE_USER_ALIGN (enumtype); TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype); } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 5c36132d391..75fed4674ff 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2297,6 +2297,7 @@ finish_builtin_type (type, name, fields, len, align_type) } DECL_FIELD_CONTEXT (fields[i]) = type; TYPE_ALIGN (type) = TYPE_ALIGN (align_type); + TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (align_type); layout_type (type); #if 0 /* not yet, should get fixed properly later */ TYPE_NAME (type) = make_type_decl (get_identifier (name), type); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 238b7fceefa..bb07c1bb8f2 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -74,6 +74,7 @@ void init_init_processing () /* Use the biggest alignment supported by the target to prevent operator new from returning misaligned pointers. */ TYPE_ALIGN (BI_header_type) = BIGGEST_ALIGNMENT; + TYPE_USER_ALIGN (BI_header_type) = 0; finish_builtin_type (BI_header_type, "__new_cookie", fields, 0, BI_header_type); BI_header_size = size_in_bytes (BI_header_type); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index cd584c28cae..625fc1a08bb 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4930,6 +4930,7 @@ instantiate_class_template (type) = TYPE_USES_VIRTUAL_BASECLASSES (pattern); TYPE_PACKED (type) = TYPE_PACKED (pattern); TYPE_ALIGN (type) = TYPE_ALIGN (pattern); + TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (pattern); TYPE_FOR_JAVA (type) = TYPE_FOR_JAVA (pattern); /* For libjava's JArray */ if (ANON_AGGR_TYPE_P (pattern)) SET_ANON_AGGR_TYPE_P (type); diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 45c4c64d12e..3dd1845f4b8 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -438,6 +438,7 @@ get_tinfo_decl (type) DECL_ARTIFICIAL (d) = 1; DECL_ALIGN (d) = TYPE_ALIGN (ptr_type_node); + DECL_USER_ALIGN (d) = 0; TREE_READONLY (d) = 1; TREE_STATIC (d) = 1; DECL_EXTERNAL (d) = 1; @@ -1180,6 +1181,7 @@ synthesize_tinfo_fn (fndecl) DECL_COMMON (tdecl) = 1; TREE_USED (tdecl) = 1; DECL_ALIGN (tdecl) = TYPE_ALIGN (ptr_type_node); + DECL_USER_ALIGN (tdecl) = 0; cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0); /* Begin processing the function. */ diff --git a/gcc/f/ChangeLog b/gcc/f/ChangeLog index a31553bf370..e1efb7fb598 100644 --- a/gcc/f/ChangeLog +++ b/gcc/f/ChangeLog @@ -1,3 +1,10 @@ +2000-06-13 Jakub Jelinek + + * com.c (ffecom_transform_common_): Set DECL_USER_ALIGN. + (ffecom_transform_equiv_, ffecom_decl_field): Likewise. + (ffecom_init_0): Set DECL_USER_ALIGN resp. TYPE_USER_ALIGN. + (duplicate_decls): Set DECL_USER_ALIGN. + Sun Jun 11 00:03:00 2000 Kaveh R. Ghazi * com.c (lang_get_alias_set): Mark parameter with ATTRIBUTE_UNUSED. diff --git a/gcc/f/com.c b/gcc/f/com.c index 7d593fd5b7a..7611d2408a3 100644 --- a/gcc/f/com.c +++ b/gcc/f/com.c @@ -8801,6 +8801,7 @@ ffecom_transform_common_ (ffesymbol s) this seems easy enough. */ DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT; + DECL_USER_ALIGN (cbt) = 0; if (is_init && (ffestorag_init (st) == NULL)) init = ffecom_init_zero_ (cbt); @@ -8936,6 +8937,7 @@ ffecom_transform_equiv_ (ffestorag eqst) this seems easy enough. */ DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT; + DECL_USER_ALIGN (eqt) = 0; if ((!is_init && ffe_is_init_local_zero ()) || (is_init && (ffestorag_init (eqst) == NULL))) @@ -10999,6 +11001,7 @@ ffecom_decl_field (tree context, tree prevfield, field = build_decl (FIELD_DECL, get_identifier (name), type); DECL_CONTEXT (field) = context; DECL_ALIGN (field) = 0; + DECL_USER_ALIGN (field) = 0; if (prevfield != NULL_TREE) TREE_CHAIN (prevfield) = field; @@ -11634,6 +11637,7 @@ ffecom_init_0 () /* We are not going to have real types in C with less than byte alignment, so we might as well not have any types that claim to have it. */ TYPE_ALIGN (void_type_node) = BITS_PER_UNIT; + TYPE_USER_ALIGN (void_type_node) = 0; string_type_node = build_pointer_type (char_type_node); @@ -12055,6 +12059,7 @@ ffecom_init_0 () DECL_CONTEXT (ffecom_multi_fields_[i][j]) = ffecom_multi_type_node_; DECL_ALIGN (ffecom_multi_fields_[i][j]) = 0; + DECL_USER_ALIGN (ffecom_multi_fields_[i][j]) = 0; TREE_CHAIN (ffecom_multi_fields_[i][j]) = field; field = ffecom_multi_fields_[i][j]; } @@ -13783,7 +13788,10 @@ duplicate_decls (tree newdecl, tree olddecl) DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl); if (TREE_CODE (olddecl) != FUNCTION_DECL) if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl)) - DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl); + { + DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl); + DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl); + } } /* Keep the old rtl since we can safely use it. */ diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index ca638d747ab..b19bc570c35 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,9 @@ +2000-06-13 Jakub Jelinek + + * typeck.c (build_java_array_type): Set TYPE_USER_ALIGN. + * parse.y (java_complete_class): Set DECL_USER_ALIGN. + * parse.c: Rebuilt. + 2000-06-11 Kaveh R. Ghazi * decl.c (create_primitive_vtable): Prototype. diff --git a/gcc/java/parse.c b/gcc/java/parse.c index fd547f27768..22c5bf1b074 100644 --- a/gcc/java/parse.c +++ b/gcc/java/parse.c @@ -7949,6 +7949,7 @@ java_complete_class () pop_obstacks (); TREE_TYPE (field_decl) = field_type; DECL_ALIGN (field_decl) = 0; + DECL_USER_ALIGN (field_decl) = 0; layout_decl (field_decl, 0); SOURCE_FRONTEND_DEBUG (("Completed field/var decl `%s' with `%s'", diff --git a/gcc/java/parse.y b/gcc/java/parse.y index e6b353791b7..6b13e0c6614 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -5249,6 +5249,7 @@ java_complete_class () pop_obstacks (); TREE_TYPE (field_decl) = field_type; DECL_ALIGN (field_decl) = 0; + DECL_USER_ALIGN (field_decl) = 0; layout_decl (field_decl, 0); SOURCE_FRONTEND_DEBUG (("Completed field/var decl `%s' with `%s'", diff --git a/gcc/java/typeck.c b/gcc/java/typeck.c index 4309cfbfff1..1a7256d6482 100644 --- a/gcc/java/typeck.c +++ b/gcc/java/typeck.c @@ -421,7 +421,10 @@ build_java_array_type (element_type, length) TREE_CHAIN (fld) = arfld; } else - TYPE_ALIGN (t) = TYPE_ALIGN (element_type); + { + TYPE_ALIGN (t) = TYPE_ALIGN (element_type); + TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (element_type); + } pop_obstacks (); /* We could layout_class, but that loads java.lang.Object prematurely. diff --git a/gcc/stmt.c b/gcc/stmt.c index 14ce4a9b39e..f97faaa0081 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -3849,6 +3849,7 @@ expand_decl (decl) /* Set alignment we actually gave this decl. */ DECL_ALIGN (decl) = (DECL_MODE (decl) == BLKmode ? BIGGEST_ALIGNMENT : GET_MODE_BITSIZE (DECL_MODE (decl))); + DECL_USER_ALIGN (decl) = 0; if (oldaddr) { @@ -3901,6 +3902,7 @@ expand_decl (decl) #else DECL_ALIGN (decl) = BIGGEST_ALIGNMENT; #endif + DECL_USER_ALIGN (decl) = 0; } } @@ -4204,6 +4206,7 @@ expand_anon_union_decl (decl, cleanup, decl_elts) /* Propagate the union's alignment to the elements. */ DECL_ALIGN (decl_elt) = DECL_ALIGN (decl); + DECL_USER_ALIGN (decl_elt) = DECL_USER_ALIGN (decl); /* If the element has BLKmode and the union doesn't, the union is aligned such that the element doesn't need to have BLKmode, so diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index b28432bd848..65ac15b12bc 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -330,7 +330,10 @@ layout_decl (decl, known_align) && (DECL_ALIGN (decl) == 0 || (! (code == FIELD_DECL && DECL_PACKED (decl)) && TYPE_ALIGN (type) > DECL_ALIGN (decl)))) - DECL_ALIGN (decl) = TYPE_ALIGN (type); + { + DECL_ALIGN (decl) = TYPE_ALIGN (type); + DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type); + } /* For fields, set the bit field type and update the alignment. */ if (code == FIELD_DECL) @@ -339,7 +342,10 @@ layout_decl (decl, known_align) if (maximum_field_alignment != 0) DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment); else if (DECL_PACKED (decl)) - DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT); + { + DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT); + DECL_USER_ALIGN (decl) = 0; + } } /* See if we can use an ordinary integer mode for a bit-field. @@ -572,14 +578,27 @@ place_union_field (rli, field) record_layout_info rli; tree field; { + unsigned int desired_align; + layout_decl (field, 0); DECL_FIELD_OFFSET (field) = size_zero_node; DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node; DECL_OFFSET_ALIGN (field) = BIGGEST_ALIGNMENT; + desired_align = DECL_ALIGN (field); + +#ifdef BIGGEST_FIELD_ALIGNMENT + /* Some targets (i.e. i386) limit union field alignment + to a lower boundary than alignment of variables unless + it was overridden by attribute aligned. */ + if (! DECL_USER_ALIGN (field)) + desired_align = + MIN (desired_align, (unsigned) BIGGEST_FIELD_ALIGNMENT); +#endif + /* Union must be at least as aligned as any field requires. */ - rli->record_align = MAX (rli->record_align, DECL_ALIGN (field)); + rli->record_align = MAX (rli->record_align, desired_align); #ifdef PCC_BITFIELD_TYPE_MATTERS /* On the m88000, a bit field of declare type `int' forces the @@ -615,6 +634,7 @@ place_field (rli, field) record as it presently stands. */ unsigned int known_align; unsigned int actual_align; + unsigned int user_align; /* The type of this field. */ tree type = TREE_TYPE (field); @@ -660,14 +680,21 @@ place_field (rli, field) packed field, use the alignment as specified, disregarding what the type would want. */ desired_align = DECL_ALIGN (field); + user_align = DECL_USER_ALIGN (field); layout_decl (field, known_align); if (! DECL_PACKED (field)) - desired_align = DECL_ALIGN (field); + { + desired_align = DECL_ALIGN (field); + user_align = DECL_USER_ALIGN (field); + } - /* Some targets (i.e. VMS) limit struct field alignment - to a lower boundary than alignment of variables. */ #ifdef BIGGEST_FIELD_ALIGNMENT - desired_align = MIN (desired_align, (unsigned) BIGGEST_FIELD_ALIGNMENT); + /* Some targets (i.e. i386, VMS) limit struct field alignment + to a lower boundary than alignment of variables unless + it was overridden by attribute aligned. */ + if (! user_align) + desired_align = + MIN (desired_align, (unsigned) BIGGEST_FIELD_ALIGNMENT); #endif #ifdef ADJUST_FIELD_ALIGN desired_align = ADJUST_FIELD_ALIGN (field, desired_align); @@ -902,6 +929,7 @@ finalize_record_size (rli) #else TYPE_ALIGN (rli->t) = MAX (TYPE_ALIGN (rli->t), rli->record_align); #endif + TYPE_USER_ALIGN (rli->t) = 1; /* Compute the size so far. Be sure to allow for extra bits in the size in bytes. We have guaranteed above that it will be no more @@ -1083,7 +1111,10 @@ finalize_type_size (type) || (TREE_CODE (type) != RECORD_TYPE && TREE_CODE (type) != UNION_TYPE && TREE_CODE (type) != QUAL_UNION_TYPE && TREE_CODE (type) != ARRAY_TYPE))) - TYPE_ALIGN (type) = GET_MODE_ALIGNMENT (TYPE_MODE (type)); + { + TYPE_ALIGN (type) = GET_MODE_ALIGNMENT (TYPE_MODE (type)); + TYPE_USER_ALIGN (type) = 0; + } /* Do machine-dependent extra alignment. */ #ifdef ROUND_TYPE_ALIGN @@ -1133,6 +1164,7 @@ finalize_type_size (type) tree size = TYPE_SIZE (type); tree size_unit = TYPE_SIZE_UNIT (type); unsigned int align = TYPE_ALIGN (type); + unsigned int user_align = TYPE_USER_ALIGN (type); enum machine_mode mode = TYPE_MODE (type); /* Copy it into all variants. */ @@ -1143,6 +1175,7 @@ finalize_type_size (type) TYPE_SIZE (variant) = size; TYPE_SIZE_UNIT (variant) = size_unit; TYPE_ALIGN (variant) = align; + TYPE_USER_ALIGN (variant) = user_align; TYPE_MODE (variant) = mode; } } @@ -1256,6 +1289,7 @@ layout_type (type) case VOID_TYPE: /* This is an incomplete type and so doesn't have a size. */ TYPE_ALIGN (type) = 1; + TYPE_USER_ALIGN (type) = 0; TYPE_MODE (type) = VOIDmode; break; @@ -1460,6 +1494,7 @@ layout_type (type) TYPE_SIZE (type) = bitsize_int (rounded_size); TYPE_SIZE_UNIT (type) = size_int (rounded_size / BITS_PER_UNIT); TYPE_ALIGN (type) = alignment; + TYPE_USER_ALIGN (type) = 0; TYPE_PRECISION (type) = size_in_bits; } break; @@ -1468,6 +1503,7 @@ layout_type (type) /* The size may vary in different languages, so the language front end should fill in the size. */ TYPE_ALIGN (type) = BIGGEST_ALIGNMENT; + TYPE_USER_ALIGN (type) = 0; TYPE_MODE (type) = BLKmode; break; @@ -1534,6 +1570,7 @@ initialize_sizetypes () TYPE_MODE (t) = SImode; TYPE_ALIGN (t) = GET_MODE_ALIGNMENT (SImode); + TYPE_USER_ALIGN (t) = 0; TYPE_SIZE (t) = build_int_2 (GET_MODE_BITSIZE (SImode), 0); TYPE_SIZE_UNIT (t) = build_int_2 (GET_MODE_SIZE (SImode), 0); TREE_UNSIGNED (t) = 1; diff --git a/gcc/tm.texi b/gcc/tm.texi index 90e5e908fee..458b9ba50fe 100644 --- a/gcc/tm.texi +++ b/gcc/tm.texi @@ -849,9 +849,10 @@ on machines that don't have byte or half-word store operations. @findex BIGGEST_FIELD_ALIGNMENT @item BIGGEST_FIELD_ALIGNMENT -Biggest alignment that any structure field can require on this machine, -in bits. If defined, this overrides @code{BIGGEST_ALIGNMENT} for -structure fields only. +Biggest alignment that any structure or union field can require on this +machine, in bits. If defined, this overrides @code{BIGGEST_ALIGNMENT} for +structure and union fields only, unless the field alignment has been set +by the @code{__attribute__ ((aligned (@var{n})))} construct. @findex ADJUST_FIELD_ALIGN @item ADJUST_FIELD_ALIGN (@var{field}, @var{computed}) diff --git a/gcc/tree.c b/gcc/tree.c index 10324030262..933bba81fd5 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -1063,6 +1063,7 @@ make_node (code) case 'd': if (code != FUNCTION_DECL) DECL_ALIGN (t) = 1; + DECL_USER_ALIGN (t) = 0; DECL_IN_SYSTEM_HEADER (t) = in_system_header; DECL_SOURCE_LINE (t) = lineno; DECL_SOURCE_FILE (t) = @@ -1076,6 +1077,7 @@ make_node (code) case 't': TYPE_UID (t) = next_type_uid++; TYPE_ALIGN (t) = 1; + TYPE_USER_ALIGN (t) = 0; TYPE_MAIN_VARIANT (t) = t; TYPE_OBSTACK (t) = obstack; TYPE_ATTRIBUTES (t) = NULL_TREE; @@ -4649,6 +4651,7 @@ build_index_type (maxval) TYPE_SIZE (itype) = TYPE_SIZE (sizetype); TYPE_SIZE_UNIT (itype) = TYPE_SIZE_UNIT (sizetype); TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype); + TYPE_USER_ALIGN (itype) = TYPE_USER_ALIGN (sizetype); if (host_integerp (maxval, 1)) return type_hash_canon (tree_low_cst (maxval, 1), itype); @@ -4681,6 +4684,7 @@ build_range_type (type, lowval, highval) TYPE_SIZE (itype) = TYPE_SIZE (type); TYPE_SIZE_UNIT (itype) = TYPE_SIZE_UNIT (type); TYPE_ALIGN (itype) = TYPE_ALIGN (type); + TYPE_USER_ALIGN (itype) = TYPE_USER_ALIGN (type); if (host_integerp (lowval, 0) && highval != 0 && host_integerp (highval, 0)) return type_hash_canon (tree_low_cst (highval, 0) @@ -5714,6 +5718,7 @@ build_common_tree_nodes_2 (short_double) /* We are not going to have real types in C with less than byte alignment, so we might as well not have any types that claim to have it. */ TYPE_ALIGN (void_type_node) = BITS_PER_UNIT; + TYPE_USER_ALIGN (void_type_node) = 0; null_pointer_node = build_int_2 (0, 0); TREE_TYPE (null_pointer_node) = build_pointer_type (void_type_node); diff --git a/gcc/tree.h b/gcc/tree.h index 5f5488d6555..1b68a461d7f 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -931,6 +931,10 @@ struct tree_block The value is an int, measured in bits. */ #define TYPE_ALIGN(NODE) (TYPE_CHECK (NODE)->type.align) +/* 1 if the alignment for this type was requested by "aligned" attribute, + 0 if it is the default for this type. */ +#define TYPE_USER_ALIGN(NODE) (TYPE_CHECK (NODE)->type.user_align) + /* The alignment for NODE, in bytes. */ #define TYPE_ALIGN_UNIT(NODE) \ (TYPE_ALIGN (NODE) / BITS_PER_UNIT) @@ -1113,6 +1117,7 @@ struct tree_type unsigned lang_flag_4 : 1; unsigned lang_flag_5 : 1; unsigned lang_flag_6 : 1; + unsigned user_align : 1; unsigned int align; union tree_node *pointer_to; @@ -1297,6 +1302,9 @@ struct tree_type #define DECL_ALIGN(NODE) (DECL_CHECK (NODE)->decl.u1.a.align) /* For FIELD_DECLs, holds the alignment that DECL_FIELD_OFFSET has. */ #define DECL_OFFSET_ALIGN(NODE) (FIELD_DECL_CHECK (NODE)->decl.u1.a.off_align) +/* 1 if the alignment for this type was requested by "aligned" attribute, + 0 if it is the default for this type. */ +#define DECL_USER_ALIGN(NODE) (DECL_CHECK (NODE)->decl.user_align) /* Holds the machine mode corresponding to the declaration of a variable or field. Always equal to TYPE_MODE (TREE_TYPE (decl)) except for a FIELD_DECL. */ @@ -1595,7 +1603,8 @@ struct tree_decl unsigned pure_flag : 1; unsigned pointer_depth : 2; unsigned non_addressable : 1; - /* Four unused bits. */ + unsigned user_align : 1; + /* Three unused bits. */ unsigned lang_flag_0 : 1; unsigned lang_flag_1 : 1;