diff options
Diffstat (limited to 'gcc/stor-layout.c')
-rw-r--r-- | gcc/stor-layout.c | 140 |
1 files changed, 77 insertions, 63 deletions
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index dd40ca00af..10e9a32494 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -1,5 +1,5 @@ /* C-compiler utilities for types and variables storage layout - Copyright (C) 1987-2016 Free Software Foundation, Inc. + Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of GCC. @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "rtl.h" #include "tree.h" +#include "memmodel.h" #include "tm_p.h" #include "stringpool.h" #include "regs.h" @@ -398,7 +399,7 @@ int_mode_for_mode (machine_mode mode) if (mode == BLKmode) break; - /* ... fall through ... */ + /* fall through */ case MODE_CC: default: @@ -565,7 +566,7 @@ do_type_align (tree type, tree decl) { if (TYPE_ALIGN (type) > DECL_ALIGN (decl)) { - DECL_ALIGN (decl) = TYPE_ALIGN (type); + SET_DECL_ALIGN (decl, TYPE_ALIGN (type)); if (TREE_CODE (decl) == FIELD_DECL) DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type); } @@ -596,7 +597,7 @@ layout_decl (tree decl, unsigned int known_align) return; gcc_assert (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL - || code == TYPE_DECL ||code == FIELD_DECL); + || code == TYPE_DECL || code == FIELD_DECL); rtl = DECL_RTL_IF_SET (decl); @@ -615,7 +616,7 @@ layout_decl (tree decl, unsigned int known_align) DECL_UNSIGNED (decl) = TYPE_UNSIGNED (type); if (DECL_MODE (decl) == VOIDmode) - DECL_MODE (decl) = TYPE_MODE (type); + SET_DECL_MODE (decl, TYPE_MODE (type)); if (DECL_SIZE (decl) == 0) { @@ -658,7 +659,7 @@ layout_decl (tree decl, unsigned int known_align) #ifdef EMPTY_FIELD_BOUNDARY if (EMPTY_FIELD_BOUNDARY > DECL_ALIGN (decl)) { - DECL_ALIGN (decl) = EMPTY_FIELD_BOUNDARY; + SET_DECL_ALIGN (decl, EMPTY_FIELD_BOUNDARY); DECL_USER_ALIGN (decl) = 0; } #endif @@ -680,8 +681,8 @@ layout_decl (tree decl, unsigned int known_align) && !(xalign > BITS_PER_UNIT && DECL_PACKED (decl)) && (known_align == 0 || known_align >= xalign)) { - DECL_ALIGN (decl) = MAX (xalign, DECL_ALIGN (decl)); - DECL_MODE (decl) = xmode; + SET_DECL_ALIGN (decl, MAX (xalign, DECL_ALIGN (decl))); + SET_DECL_MODE (decl, xmode); DECL_BIT_FIELD (decl) = 0; } } @@ -705,7 +706,7 @@ layout_decl (tree decl, unsigned int known_align) DECL_USER_ALIGN, so we need to check old_user_align instead. */ if (packed_p && !old_user_align) - DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT); + SET_DECL_ALIGN (decl, MIN (DECL_ALIGN (decl), BITS_PER_UNIT)); if (! packed_p && ! DECL_USER_ALIGN (decl)) { @@ -713,11 +714,12 @@ layout_decl (tree decl, unsigned int known_align) to a lower boundary than alignment of variables unless it was overridden by attribute aligned. */ #ifdef BIGGEST_FIELD_ALIGNMENT - DECL_ALIGN (decl) - = MIN (DECL_ALIGN (decl), (unsigned) BIGGEST_FIELD_ALIGNMENT); + SET_DECL_ALIGN (decl, MIN (DECL_ALIGN (decl), + (unsigned) BIGGEST_FIELD_ALIGNMENT)); #endif #ifdef ADJUST_FIELD_ALIGN - DECL_ALIGN (decl) = ADJUST_FIELD_ALIGN (decl, DECL_ALIGN (decl)); + SET_DECL_ALIGN (decl, ADJUST_FIELD_ALIGN (decl, TREE_TYPE (decl), + DECL_ALIGN (decl))); #endif } @@ -727,7 +729,7 @@ layout_decl (tree decl, unsigned int known_align) mfa = maximum_field_alignment; /* Should this be controlled by DECL_USER_ALIGN, too? */ if (mfa != 0) - DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), mfa); + SET_DECL_ALIGN (decl, MIN (DECL_ALIGN (decl), mfa)); } /* Evaluate nonconstant size only once, either now or as soon as safe. */ @@ -768,17 +770,18 @@ layout_decl (tree decl, unsigned int known_align) } } -/* Given a VAR_DECL, PARM_DECL or RESULT_DECL, clears the results of - a previous call to layout_decl and calls it again. */ +/* Given a VAR_DECL, PARM_DECL, RESULT_DECL, or FIELD_DECL, clears the + results of a previous call to layout_decl and calls it again. */ void relayout_decl (tree decl) { DECL_SIZE (decl) = DECL_SIZE_UNIT (decl) = 0; - DECL_MODE (decl) = VOIDmode; + SET_DECL_MODE (decl, VOIDmode); if (!DECL_USER_ALIGN (decl)) - DECL_ALIGN (decl) = 0; - SET_DECL_RTL (decl, 0); + SET_DECL_ALIGN (decl, 0); + if (DECL_RTL_SET_P (decl)) + SET_DECL_RTL (decl, 0); layout_decl (decl, 0); } @@ -1030,7 +1033,7 @@ update_alignment_for_field (record_layout_info rli, tree field, #ifdef ADJUST_FIELD_ALIGN if (! TYPE_USER_ALIGN (type)) - type_align = ADJUST_FIELD_ALIGN (field, type_align); + type_align = ADJUST_FIELD_ALIGN (field, type, type_align); #endif /* Targets might chose to handle unnamed and hence possibly @@ -1088,6 +1091,10 @@ place_union_field (record_layout_info rli, tree field) if (TREE_CODE (TREE_TYPE (field)) == ERROR_MARK) return; + if (AGGREGATE_TYPE_P (TREE_TYPE (field)) + && TYPE_TYPELESS_STORAGE (TREE_TYPE (field))) + TYPE_TYPELESS_STORAGE (rli->t) = 1; + /* We assume the union's size will be a multiple of a byte so we don't bother with BITPOS. */ if (TREE_CODE (rli->t) == UNION_TYPE) @@ -1136,7 +1143,7 @@ place_field (record_layout_info rli, tree field) really like a structure field. If it is a FUNCTION_DECL, it's a method. In both cases, all we do is lay out the decl, and we do it *after* the record is laid out. */ - if (TREE_CODE (field) == VAR_DECL) + if (VAR_P (field)) { vec_safe_push (rli->pending_statics, field); return; @@ -1165,17 +1172,19 @@ place_field (record_layout_info rli, tree field) return; } + if (AGGREGATE_TYPE_P (type) + && TYPE_TYPELESS_STORAGE (type)) + TYPE_TYPELESS_STORAGE (rli->t) = 1; + /* Work out the known alignment so far. Note that A & (-A) is the value of the least-significant bit in A that is one. */ if (! integer_zerop (rli->bitpos)) - known_align = (tree_to_uhwi (rli->bitpos) - & - tree_to_uhwi (rli->bitpos)); + known_align = least_bit_hwi (tree_to_uhwi (rli->bitpos)); else if (integer_zerop (rli->offset)) known_align = 0; else if (tree_fits_uhwi_p (rli->offset)) known_align = (BITS_PER_UNIT - * (tree_to_uhwi (rli->offset) - & - tree_to_uhwi (rli->offset))); + * least_bit_hwi (tree_to_uhwi (rli->offset))); else known_align = rli->offset_align; @@ -1260,7 +1269,7 @@ place_field (record_layout_info rli, tree field) #ifdef ADJUST_FIELD_ALIGN if (! TYPE_USER_ALIGN (type)) - type_align = ADJUST_FIELD_ALIGN (field, type_align); + type_align = ADJUST_FIELD_ALIGN (field, type, type_align); #endif /* A bit field may not span more units of alignment of its type @@ -1303,7 +1312,7 @@ place_field (record_layout_info rli, tree field) #ifdef ADJUST_FIELD_ALIGN if (! TYPE_USER_ALIGN (type)) - type_align = ADJUST_FIELD_ALIGN (field, type_align); + type_align = ADJUST_FIELD_ALIGN (field, type, type_align); #endif if (maximum_field_alignment != 0) @@ -1478,14 +1487,12 @@ place_field (record_layout_info rli, tree field) approximate this by seeing if its position changed), lay out the field again; perhaps we can use an integral mode for it now. */ if (! integer_zerop (DECL_FIELD_BIT_OFFSET (field))) - actual_align = (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field)) - & - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))); + actual_align = least_bit_hwi (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))); else if (integer_zerop (DECL_FIELD_OFFSET (field))) actual_align = MAX (BIGGEST_ALIGNMENT, rli->record_align); else if (tree_fits_uhwi_p (DECL_FIELD_OFFSET (field))) actual_align = (BITS_PER_UNIT - * (tree_to_uhwi (DECL_FIELD_OFFSET (field)) - & - tree_to_uhwi (DECL_FIELD_OFFSET (field)))); + * least_bit_hwi (tree_to_uhwi (DECL_FIELD_OFFSET (field)))); else actual_align = DECL_OFFSET_ALIGN (field); /* ACTUAL_ALIGN is still the actual alignment *within the record* . @@ -1558,10 +1565,10 @@ finalize_record_size (record_layout_info rli) /* Determine the desired alignment. */ #ifdef ROUND_TYPE_ALIGN - TYPE_ALIGN (rli->t) = ROUND_TYPE_ALIGN (rli->t, TYPE_ALIGN (rli->t), - rli->record_align); + SET_TYPE_ALIGN (rli->t, ROUND_TYPE_ALIGN (rli->t, TYPE_ALIGN (rli->t), + rli->record_align)); #else - TYPE_ALIGN (rli->t) = MAX (TYPE_ALIGN (rli->t), rli->record_align); + SET_TYPE_ALIGN (rli->t, MAX (TYPE_ALIGN (rli->t), rli->record_align)); #endif /* Compute the size so far. Be sure to allow for extra bits in the @@ -1718,15 +1725,15 @@ finalize_type_size (tree type) alignment of one of the fields. */ if (mode_align >= TYPE_ALIGN (type)) { - TYPE_ALIGN (type) = mode_align; + SET_TYPE_ALIGN (type, mode_align); TYPE_USER_ALIGN (type) = 0; } } /* Do machine-dependent extra alignment. */ #ifdef ROUND_TYPE_ALIGN - TYPE_ALIGN (type) - = ROUND_TYPE_ALIGN (type, TYPE_ALIGN (type), BITS_PER_UNIT); + SET_TYPE_ALIGN (type, + ROUND_TYPE_ALIGN (type, TYPE_ALIGN (type), BITS_PER_UNIT)); #endif /* If we failed to find a simple way to calculate the unit size @@ -1779,7 +1786,7 @@ finalize_type_size (tree type) valign = MAX (valign, TYPE_ALIGN (variant)); else TYPE_USER_ALIGN (variant) = user_align; - TYPE_ALIGN (variant) = valign; + SET_TYPE_ALIGN (variant, valign); TYPE_PRECISION (variant) = precision; SET_TYPE_MODE (variant, mode); } @@ -1808,6 +1815,11 @@ start_bitfield_representative (tree field) DECL_SIZE_UNIT (repr) = DECL_SIZE_UNIT (field); DECL_PACKED (repr) = DECL_PACKED (field); DECL_CONTEXT (repr) = DECL_CONTEXT (field); + /* There are no indirect accesses to this field. If we introduce + some then they have to use the record alias set. This makes + sure to properly conflict with [indirect] accesses to addressable + fields of the bitfield group. */ + DECL_NONADDRESSABLE_P (repr) = 1; return repr; } @@ -1861,13 +1873,14 @@ finish_bitfield_representative (tree repr, tree field) } else { - /* ??? If you consider that tail-padding of this struct might be - re-used when deriving from it we cannot really do the following - and thus need to set maxsize to bitsize? Also we cannot - generally rely on maxsize to fold to an integer constant, so - use bitsize as fallback for this case. */ - tree maxsize = size_diffop (TYPE_SIZE_UNIT (DECL_CONTEXT (field)), - DECL_FIELD_OFFSET (repr)); + /* Note that if the C++ FE sets up tail-padding to be re-used it + creates a as-base variant of the type with TYPE_SIZE adjusted + accordingly. So it is safe to include tail-padding here. */ + tree aggsize = lang_hooks.types.unit_size_without_reusable_padding + (DECL_CONTEXT (field)); + tree maxsize = size_diffop (aggsize, DECL_FIELD_OFFSET (repr)); + /* We cannot generally rely on maxsize to fold to an integer constant, + so use bitsize as fallback for this case. */ if (tree_fits_uhwi_p (maxsize)) maxbitsize = (tree_to_uhwi (maxsize) * BITS_PER_UNIT - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr))); @@ -1903,7 +1916,7 @@ finish_bitfield_representative (tree repr, tree field) [0, 15] HImode for a and b, [8, 23] HImode for c. */ DECL_SIZE (repr) = bitsize_int (bitsize); DECL_SIZE_UNIT (repr) = size_int (bitsize / BITS_PER_UNIT); - DECL_MODE (repr) = BLKmode; + SET_DECL_MODE (repr, BLKmode); TREE_TYPE (repr) = build_array_type_nelts (unsigned_char_type_node, bitsize / BITS_PER_UNIT); } @@ -1912,7 +1925,7 @@ finish_bitfield_representative (tree repr, tree field) unsigned HOST_WIDE_INT modesize = GET_MODE_BITSIZE (mode); DECL_SIZE (repr) = bitsize_int (modesize); DECL_SIZE_UNIT (repr) = size_int (modesize / BITS_PER_UNIT); - DECL_MODE (repr) = mode; + SET_DECL_MODE (repr, mode); TREE_TYPE (repr) = lang_hooks.types.type_for_mode (mode, 1); } @@ -2073,7 +2086,7 @@ finish_builtin_struct (tree type, const char *name, tree fields, if (align_type) { - TYPE_ALIGN (type) = TYPE_ALIGN (align_type); + SET_TYPE_ALIGN (type, TYPE_ALIGN (align_type)); TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (align_type); } @@ -2132,8 +2145,11 @@ layout_type (tree type) break; case REAL_TYPE: - SET_TYPE_MODE (type, - mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0)); + /* Allow the caller to choose the type mode, which is how decimal + floats are distinguished from binary ones. */ + if (TYPE_MODE (type) == VOIDmode) + SET_TYPE_MODE (type, + mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0)); TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type))); TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type))); break; @@ -2184,7 +2200,7 @@ layout_type (tree type) Instead, query a target hook, defaulting to natural alignment. This prevents ABI changes depending on whether or not native vector modes are supported. */ - TYPE_ALIGN (type) = targetm.vector_alignment (type); + SET_TYPE_ALIGN (type, targetm.vector_alignment (type)); /* However, if the underlying mode requires a bigger alignment than what the target hook provides, we cannot use the mode. For now, @@ -2196,7 +2212,7 @@ layout_type (tree type) case VOID_TYPE: /* This is an incomplete type and so doesn't have a size. */ - TYPE_ALIGN (type) = 1; + SET_TYPE_ALIGN (type, 1); TYPE_USER_ALIGN (type) = 0; SET_TYPE_MODE (type, VOIDmode); break; @@ -2241,8 +2257,6 @@ layout_type (tree type) tree index = TYPE_DOMAIN (type); tree element = TREE_TYPE (type); - build_pointer_type (element); - /* We need to know both bounds in order to compute the size. */ if (index && TYPE_MAX_VALUE (index) && TYPE_MIN_VALUE (index) && TYPE_SIZE (element)) @@ -2315,7 +2329,7 @@ layout_type (tree type) #else align = MAX (align, BITS_PER_UNIT); #endif - TYPE_ALIGN (type) = align; + SET_TYPE_ALIGN (type, align); SET_TYPE_MODE (type, BLKmode); if (TYPE_SIZE (type) != 0 && ! targetm.member_type_forces_blk (type, VOIDmode) @@ -2334,6 +2348,8 @@ layout_type (tree type) SET_TYPE_MODE (type, BLKmode); } } + if (AGGREGATE_TYPE_P (element)) + TYPE_TYPELESS_STORAGE (type) = TYPE_TYPELESS_STORAGE (element); /* When the element size is constant, check that it is at least as large as the element alignment. */ if (TYPE_SIZE_UNIT (element) @@ -2406,9 +2422,7 @@ min_align_of_type (tree type) #endif unsigned int field_align = align; #ifdef ADJUST_FIELD_ALIGN - tree field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, type); - field_align = ADJUST_FIELD_ALIGN (field, field_align); - ggc_free (field); + field_align = ADJUST_FIELD_ALIGN (NULL_TREE, type, field_align); #endif align = MIN (align, field_align); } @@ -2569,7 +2583,7 @@ initialize_sizetypes (void) } bprecision - = MIN (precision + BITS_PER_UNIT_LOG + 1, MAX_FIXED_MODE_SIZE); + = MIN (precision + LOG2_BITS_PER_UNIT + 1, MAX_FIXED_MODE_SIZE); bprecision = GET_MODE_PRECISION (smallest_mode_for_size (bprecision, MODE_INT)); if (bprecision > HOST_BITS_PER_DOUBLE_INT) @@ -2587,13 +2601,13 @@ initialize_sizetypes (void) /* Now layout both types manually. */ SET_TYPE_MODE (sizetype, smallest_mode_for_size (precision, MODE_INT)); - TYPE_ALIGN (sizetype) = GET_MODE_ALIGNMENT (TYPE_MODE (sizetype)); + SET_TYPE_ALIGN (sizetype, GET_MODE_ALIGNMENT (TYPE_MODE (sizetype))); TYPE_SIZE (sizetype) = bitsize_int (precision); TYPE_SIZE_UNIT (sizetype) = size_int (GET_MODE_SIZE (TYPE_MODE (sizetype))); set_min_and_max_values_for_integral_type (sizetype, precision, UNSIGNED); SET_TYPE_MODE (bitsizetype, smallest_mode_for_size (bprecision, MODE_INT)); - TYPE_ALIGN (bitsizetype) = GET_MODE_ALIGNMENT (TYPE_MODE (bitsizetype)); + SET_TYPE_ALIGN (bitsizetype, GET_MODE_ALIGNMENT (TYPE_MODE (bitsizetype))); TYPE_SIZE (bitsizetype) = bitsize_int (bprecision); TYPE_SIZE_UNIT (bitsizetype) = size_int (GET_MODE_SIZE (TYPE_MODE (bitsizetype))); @@ -2896,13 +2910,13 @@ get_mode_bounds (machine_mode mode, int sign, } else if (sign) { - min_val = -((unsigned HOST_WIDE_INT) 1 << (size - 1)); - max_val = ((unsigned HOST_WIDE_INT) 1 << (size - 1)) - 1; + min_val = -(HOST_WIDE_INT_1U << (size - 1)); + max_val = (HOST_WIDE_INT_1U << (size - 1)) - 1; } else { min_val = 0; - max_val = ((unsigned HOST_WIDE_INT) 1 << (size - 1) << 1) - 1; + max_val = (HOST_WIDE_INT_1U << (size - 1) << 1) - 1; } *mmin = gen_int_mode (min_val, target_mode); |